I don't know what I'm doing wrong here
//This is the Bullet Class. Here All I need is the Y position (because the Bullet is going only Y. The image which is in my drawable hdpi folder contains the image of my bullet.
public class Bulletbun extends GameObject {
private int deltaY;
private android.media.Image img;
public Bulletbun(final int xPos, final int yPos, final Image img){
this.img= img;
this.xPos=xPos;
this.yPos=yPos;
}
public Bulletbun(float f, int i, int j, String string) {
// TODO Auto-generated constructor stub
}
#Override
public void draw(Graphics g){
g.drawImage (img, xPos, yPos, null);
}
#Override
void update() {
// TODO Auto-generated method stub
}
}
}
}
// Trying to make it fire from here... This is my OnClick. What I want is When I touch the button I made, an Image would shoot out on the Y position of the screen. Also If I were to hit it multiple time it would shoot more than one (5). But also destroy the ones that are off-screen to save memory.
#Override
public void onClick(View v) { //+sound
// TODO Auto-generated method stub //+sound
Bulletbun Bulletbunny= new Bulletbun(bunbutt.getX()+20, 4,4, "images/air_bunny.png");
if (barrelblast != 0)
sp.play(barrelblast, 1, 1, 0, 0, 1); //+sound
Vibrator vibe = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
vibe.vibrate(90);
smoke.setVisibility(View.VISIBLE);
Handler delayedAction = new Handler();
delayedAction.postDelayed(new Runnable() {
public void run() {
smoke.setVisibility(View.INVISIBLE);
//This is my GameObject Class
package com.ramy.fallingbarrels;
import com.badlogic.gdx.Graphics;
import android.media.Image;
public abstract class GameObject {
protected Image img;
protected int xPos;
protected int yPos;
abstract void draw (Graphics g);
abstract void update();
public Image getImg() {
return img;
}
public void setImg(Image img) {
this.img = img;
}
public int getxPos() {
return xPos;
}
public void setxPos(int xPos) {
this.xPos = xPos;
}
public int getYpos() {
return yPos;
}
public void setYpos(int ypos) {
this.yPos = ypos;
}
//I was trying to follow a tutorial. If I'm doing something wrong here please tell me. Also if there's a better way to do what I described please tell me.
Related
I'm a beginner in libGdx and I'm making a simple game.
I wrote a nested class. As you can see here:
public class classes{
public class GameObject{
//declaring section
private Texture texture;
private Texture[] spawnAnimation;
private Texture[] deathAnimation;
private Texture[] damageAnimation;
private Texture[] moveAnimation;
private Texture[] fightAnimation;
private Texture[] talkAnimation;
private SpriteBatch batch = new SpriteBatch();
private float width, height;
private float x, y;
private Sound spawnSound, touchSound, deathSound, objSound, moveSound, fightSound;
public GameObject(Texture txtr, float width, float height, float x, float y) {
this.texture = txtr;
this.width = width;
this.height = height;
this.x = x;
this.y = y;
}
//this method checks wether our game object is over an other object
public boolean isOver(GameObject obj){
if(((this.x >= obj.x) && (this.x <= (obj.x + obj.width))) && ((this.y >= obj.y) && (this.y <= (obj.y + obj.height))))
return true;
return false;
}
//this method sets the object bounds
public void setBounds(float width, float height, float x, float y){
this.width = width;
this.height = height;
this.x = x;
this.y = y;
}
//this method draws the object
public void draw(){
batch.draw(this.texture, this.width, this.height, this.x, this.y);
}
//animation setting section
public void setSpawnAnimation(Texture[] texture){
this.spawnAnimation = texture;
}
public void setDeathAnimation(Texture[] texture){
this.deathAnimation = texture;
}
public void setDamageAnimation(Texture[] texture){
this.damageAnimation = texture;
}
public void setMoveAnimation(Texture[] texture){
this.moveAnimation = texture;
}
public void setFightAnimation(Texture[] texture){
this.fightAnimation = texture;
}
public void setTalkAnimation(Texture[] texture){
this.talkAnimation = texture;
}
//sounds setting section
public void setSpawnSound(Sound sound){
this.spawnSound = sound;
}
public void setTouchSound(Sound sound){
this.touchSound = sound;
}
public void setDeathSound(Sound sound){
this.deathSound = sound;
}
public void setObjSound(Sound sound){
this.objSound = sound;
}
public void setMoveSound(Sound sound){
this.moveSound = sound;
}
public void setFightSound(Sound sound){
this.fightSound = sound;
}
//animation and behavior section
public void spawn(){
batch.begin();
for(int i=0;i<=this.spawnAnimation.length;i++){
this.texture = this.spawnAnimation[i];
this.draw();
try
{
Thread.sleep(0, 1);
}
catch (InterruptedException e)
{}
}
batch.end();
}
public void die(Texture[] deathTexture){
}
}
}
I went to the other file, in the other class, and I tried to set the object texture
public class MyGdxGame implements ApplicationListener{
Texture texture;
SpriteBatch batch;
classes.GameObject gun;
#Override
public void create()
{
batch = new SpriteBatch();
gun = new classes.GameObject(new Texture(Gdx.files.internal("gun.png")), 0, 0, 300, 300);
}
#Override
public void render()
{
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.end();
}
#Override
public void dispose()
{
}
#Override
public void resize(int width, int height)
{
}
#Override
public void pause()
{
}
#Override
public void resume()
{
}
}
once I try to access it. I face this error: aan instance for an enclosing class is required
note: I'm making this game for android. using AIDE ide which offers developing apps and games directly on your phone.
Inner classes that are declared without the keyword static are tethered to the outer class they exist in.
To fix
public static class GameObject{
Why would you want an inner class without static? Here's an example
public class Game {
private Data gameData;
class MyListener {
public void receiveNewData(Data newData) {
//update gameData with the new data
}
}
}
If MyListener was static, it would not be able to access Game's gameData
im working on a libgdx Game where you avoid Asteroids with a spaceship. When i launch my project i only see a white Screen :( Here u can see a big part of my code to understand what iam trying to do.
Main Class:
package com.me.mygdxgame;
import screen.MenuScreen;
import screen.ScreenManager;
public class MyGdxGame implements ApplicationListener {
SpriteBatch batch;
public static int WIDTH = 800 , HEIGHT = 480; // resolution
#Override
public void create() {
batch = new SpriteBatch();
ScreenManager.setScreen(new MenuScreen());
}
#Override
public void dispose() {
if(ScreenManager.getCurrentScreen() != null){
ScreenManager.getCurrentScreen().dispose();
}
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(ScreenManager.getCurrentScreen() != null){
ScreenManager.getCurrentScreen().update();
}
if(ScreenManager.getCurrentScreen() != null){
ScreenManager.getCurrentScreen().render(batch);
}
}
Screen class:
package screen;
public abstract class Screen {
public abstract void create();
public abstract void render(SpriteBatch batch);
public abstract void update();
public abstract void resize(int width, int height);
public abstract void dispose(int width, int height);
public abstract void dispose();
public abstract void pause();
public abstract void resume();
}
ScreenManager:
public class ScreenManager {
private static Screen currentScreen;
public static void setScreen(Screen screen){
if(currentScreen != null){
currentScreen.dispose();
currentScreen = screen;
currentScreen.create();
}
}
public static Screen getCurrentScreen() {
return currentScreen;
}
}
MenuScreen:
public class MenuScreen extends Screen {
private OrthoCamera cam;
private Spaceship spaceship;
#Override
public void create() {
// TODO Auto-generated method stub
cam = new OrthoCamera();
spaceship = new Spaceship();
}
#Override
public void render(SpriteBatch batch) {
// TODO Auto-generated method stub
batch.setProjectionMatrix(cam.combined);
batch.begin();
spaceship.render(batch);
batch.end();
}
#Override
public void update() {
// TODO Auto-generated method stub
cam.update();
spaceship.update();
}
Spaceship Class:
public class Spaceship extends Entity {
Texture texture;
Sprite sprite;
public Spaceship() {
texture = new Texture("spritesheet.png");
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear );
TextureRegion region = new TextureRegion(texture, 0, 312, 258, 144);
sprite = new Sprite(region);
sprite.setSize(sprite.getWidth(), sprite.getHeight());
sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
sprite.setPosition(-sprite.getWidth() / 2, -sprite.getHeight() / 2);
}
public void update() {
if (Gdx.input.isTouched()) {
pos.x = Gdx.input.getX() - MyGdxGame.WIDTH / 2;
pos.y = -Gdx.input.getY() + MyGdxGame.HEIGHT / 2;
}
}
#Override
public void render(SpriteBatch batch) {
sprite.draw(batch);
}
The problem should be in your ScreenManager. The method setScreen is incapable of initializing a screen if there is no previous screen:
public static void setScreen(Screen screen){
if(currentScreen != null){
currentScreen.dispose();
currentScreen = screen;
currentScreen.create();
}
}
Should be:
public static void setScreen(Screen screen) {
if (currentScreen != null){
currentScreen.dispose();
}
currentScreen = screen;
currentScreen.create();
}
I am working on a game.I want to add images to the applet but they do not appear there until I resize or minimize the applet.I do not know whether my image observer is wrong or not.
The images are in right path.Their in build and class folder with correct spelling. What is wrong with my code?
any help would be much appreciated.
public class game extends JApplet implements KeyListener, Runnable {
ScreenDir sd;
Image ball;
Image flower;
public void init() {
sd = new ScreenDir(this);
ball = getImage(getCodeBase(), "ball.jpg");
ballb = new Ball(50, 50, 30, 40, Color.red, ball, sd);
sd.add(ball);
flower = getImage(getCodeBase(), "flower.gif");
//class Flower is just defined like class Ball
flowerf = new Flower(60, 100, 30, 30, Color.green, flower, sd);
sd.add(flower);
}
public void paint(Graphics g) {
sd.draw(g);
}
//These are for moving the ball
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(15);
} catch (InterruptedException ex) {}}}
public class ScreenDir {
ArrayList<Object> olist;
JApplet parent;
public ScreenDir(JApplet parent) {
this.parent = parent;
olist = new ArrayList<>();
}
public void add(Object o) {
olist.add(o);
}
Image Img;
Graphics oG;
Img = parent.createImage(parent.getWidth(), parent.getHeight());
oG = offImg.getGraphics();
for(int i = 0;i<olist.size ();i++){
olist.get(i).draw(offG);
}
g.drawImage (Img,0, 0, parent);
}
public class Ball extends Object {
ScreenDir sd;
public ball(int x, int y, int w, int h, Color c, Image pi, ScreenDir sd) {
{
this.sd = sd;
}
public void draw(Graphics g) {
g.drawImage(pi, x, y, w, h, null);
}
public abstract class Object {
int x, y, w, h;
Color c;
Image pi;
public Object(int x, int y, int w, int h, Color c, Image pi) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.c = c;
this.pi = pi;
}
public abstract void draw(Graphics g) {
}
Applets load images asynchronously, so it is likely the images are not fully loaded before the applet goes to paint. But every Java component worth mentioning implements an ImageObserver that means it will get updates on image loading. So to fix the problem, change this:
g.drawImage(pi, x, y, w, h, null);
To this:
g.drawImage(pi, x, y, w, h, this);
Update
I mistakenly thought the drawImage method was part of the JApplet (which is an ImageObserver). You might simply change the method declaration & painting line to:
public void draw(Graphics g, ImageObserver io) {
g.drawImage(pi, x, y, w, h, io);
}
Then to call it, change:
sd.draw(g);
To:
sd.draw(g, this);
I would like some suggestions for the implementation object of the player.
the player can have 2 textures that will be chosen depending on the button pressed, for example, the right arrow will display a texture to the left while another texture.
I have implemented the interface inputprocessor in the class of player but I do not know why it does not seem very fair and very dynamic, so I would like some suggestions from you
thank you very much
CODE:
public class Player implements InputProcessor {
private Texture up;
private Texture down;
private Sprite player;
public Player(Texture one,Texture two){
this.up=one;
this.down=two;
player=new Sprite(one);
}
#Override
public boolean keyDown(int keycode) {
// TODO Auto-generated method stub
player.setTexture(this.down);
return false;
}
#Override
public boolean keyUp(int keycode) {
// TODO Auto-generated method stub
player.setTexture(this.up);
return false;
}
#Override
public boolean keyTyped(char character) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean scrolled(int amount) {
// TODO Auto-generated method stub
return false;
}
}
I implement the player class in this way, but I would like some suggestions for implementing best.
I'd suggest you to subclass very useful Sprite class and use TextureAtlas to contain player textures. here is the stub of implementation:
public class Player extends Sprite {
TextureAtlas textureAtlas;
public Player(TextureAtlas atlas) {
super(atlas.getRegions().get(0));
textureAtlas = atlas;
}
public void setTexture(String textureName) {
setRegion(textureAtlas.findRegion(textureName)));
}
}
Here is a very nice tutorial explaining how to use TextureAtlas.
Also, instead of implementing whole InputProcessor, use InputAdapter which provides an empty implementation of this interface. This will be much more clearer. It can be a field in your Player class:
private InputProcessor inputProcessor = new InputAdapter() {
// Override only methods you need here
};
Of course, don't forget to register this InputProcessor:
Gdx.input.setInputProcessor(inputProcessor);
I will update my answer with examples when i get home in a few hours.
It doesnt seem a good practice to listen for keys in the player class. I implemented a player class in my game some time ago and it was like this:
in the render method of your game class you implement key listeners, that invoke player.up() or player.down() or for example player.jump().
in player class in those methods, for example in jump() you set textures/animations.
I will post code examples.
public class Player {
float x;
float y;
float xSpeed;
float ySpeed;
private Animation playerRun;
private Animation playerJump;
private Animation playerStand;
private Animation current;
private Rectangle bounds;
public Player(){
playerRun = new Animation(1/10f, Assets.atlas.findRegions("run"));
playerRun.setPlayMode(Animation.PlayMode.LOOP);
//set other animations in similar way
current = playerStand;
this.x = Gdx.graphics.getWidth()/2;
this.y = Gdx.graphics.getHeight()/2;
bounds = new Rectangle(x, y, 100, 100);
}
public Rectangle getBounds(){
return bounds;
}
public void setPos(float x, float y){
this.x = x;
this.y = y;
bounds.x = x;
bounds.y = y;
}
public void changePos(float x, float y){
this.x +=x;
this.y +=y;
bounds.x += x;
bounds.y += y;
}
public void move(){
changePos(xSpeed, ySpeed);
}
public Animation animate(){
return current;
}
public void run(){
current = playerRun;
ySpeed = 0;
}
public void jump(){
current = playerJump;
ySpeed = 10;
}
and the render method in my game class was only calling players methods:
if (Gdx.input.isTouched()){
player.jump();
}
oops, forgot the most important part :
batch.draw(player.animate().getKeyFrame(time += delta), player.x, player.y);
I am currently trying to learn a little bit about programming games.
I got myself a player class extending a sprite class i wrote by myself.
Now i want to know, how i can change the image of my player object in the middle of the running game. imagine a spaceship, when pressing the right arrow key it should be a different image, inclined to the right.
now i am trying to do this:
when a button is pressed (e.g. space) setImage(the new image)
But now, when i call this method my image just disappears and the new one won't appear?
Any ideas?
My code of the Main class:
public class Game extends JPanel implements Runnable{
private static final long serialVersionUID = 1L;
public boolean isRunning;
public static final int WIDTH = 320;
public static final int HEIGHT = 240;
public static final int SCALE = 2;
private Player player;
public Game() {
addKeyListener(new TAdapter());
setFocusable(true);
requestFocus();
start();
}
public void start() {
isRunning = true;
new Thread(this).start();
}
public void stop() {
isRunning = false;
}
public void run() {
init();
while(isRunning) {
update();
repaint();
try {
Thread.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void init() {
player = new Player("/ship_blue", WIDTH - 32/2, 400);
}
public void update() {
player.update();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
drawPlayer(g2d);
}
public void drawPlayer(Graphics2D g2d) {
if(player.isVisible)g2d.drawImage(player.getImage(),(int) player.getX(), (int) player.getY(), null);
}
public static void main(String[] args) {
Game gameComponent = new Game();
Dimension size = new Dimension(WIDTH*SCALE, HEIGHT*SCALE);
JFrame frame = new JFrame("Invaders");
frame.setVisible(true);
frame.setSize(size);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(gameComponent);
}
public class TAdapter extends KeyAdapter{
public void keyPressed(KeyEvent e) {
player.keyPressed(e);
}
public void keyReleased(KeyEvent e) {
player.keyReleased(e);
}
}
}
That's the main class, now the player class in which i am trying to change the image in the onPress() method:
public class Player extends Sprite{
private double glideSpeed = .125;
private int fixY;
private int xDirection = 0;
private int yDirection = 1;
public Player(String source, int x, int y) {
this.x = x;
this.y = y;
ImageIcon ii = new ImageIcon(this.getClass().getResource(source));
setImage(ii.getImage());
setTileSize(ii.getIconWidth());
setSpeed(0.2);
fixY = y;
}
public void update() {
x += xDirection * 1.4;
glide(10);
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT) {
xDirection = 1;
}
if(key == KeyEvent.VK_LEFT) {
xDirection = -1;
}
if(key == KeyEvent.VK_SPACE) {
ImageIcon ii2 = new ImageIcon("/player_blue_negativ");
setImage(ii2.getImage()); //<-----Here I am trying to change the image
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT || key == KeyEvent.VK_LEFT) {
xDirection = 0;
}
}
public void glide(int span) {
y += yDirection * glideSpeed;
if(y - fixY > span || fixY - y > span) {
yDirection = -yDirection;
}
}
}
And to complete everything here's my sprite class:
public class Sprite {
protected double x;
protected double y;
protected int tileSize;
protected double speed;
protected Image img;
protected boolean isVisible;
public Sprite() {
isVisible = true;
}
public double getSpeed() {
return speed;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public int getTileSize() {
return tileSize;
}
public Image getImage() {
return img;
}
public boolean getVisible() {
return isVisible;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
public void setTileSize(int tileSize) {
this.tileSize = tileSize;
}
public void setImage(Image img) {
this.img = img;
}
public void die() {
isVisible = false;
}
}
if(key == KeyEvent.VK_SPACE) {
ImageIcon ii2 = new ImageIcon("/player_blue_negativ");
There is the basic problem. All images should be loaded and cached prior to an event happening. When the event occurs, use the cached image and the GUI should render immediately.
As mentioned by #camickr, the use of an ImageIcon also subtly slips from an URL to a String (presumed to represent a
File path). Stick with the URL obtained from getResource(..).
On ImageObserver.
If an ImageObserver is used to paint the image, the observer will be informed of updates to images that are asynchronously loaded. All components (e.g. JPanel) implement ImageObserver, so..
g2d.drawImage(player.getImage(),(int) player.getX(), (int) player.getY(), null);
Should be:
g2d.drawImage(player.getImage(),(int) player.getX(), (int) player.getY(), this);
Free the EDT!
class Game extends JPanel implements Runnable ..
Thread.sleep(5);
Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens.
Also don't attempt to update the GUI from anything other than the EDT.
Instead of calling Thread.sleep(n) in a Runnable, implement a Swing Timer for repeating tasks or a SwingWorker for long running tasks. See Concurrency in Swing for more details.
Use paintComponent(Graphics) for Swing components!
public void paint(Graphics g) {
Should be:
#Override
public void paintComponent(Graphics g) {
When you load the initial image you use the following without a problem:
ImageIcon ii = new ImageIcon(this.getClass().getResource(source));
When you change the image you use:
ImageIcon ii2 = new ImageIcon("/player_blue_negativ");
I'm guessing you don't find the image, probably because you don't need the "/". But why not use the same method that you know works?