I have these two classes, Bullet and EnemyJet. The Bullet class extends the Player class and the EnemyJet class extends an EnemyControl class. They are both using an arraylist which I'm trying to store and get their positions from.
public class Player extends Mob {
public List<Bullet> bullets = new ArrayList<Bullet>();
}
public class EnemyControl extends Mob {
public List<EnemyJet> enemyJet = new ArrayList<EnemyJet>();
}
Would I need to make a new class to store and test the two positions, or maybe use the Mob class they extend? How would I get the same values from the lists to compare them inside the new class?
For example, test for a collision with the bullet and the enemy jet. If so,remove the jet.
EnemyJet Class:
public class EnemyJet extends EnemyControl{
Random rdm = new Random();
private int destx, desty;
private Sprite sprite;
private int counter = 0;
private boolean dead = false;
private boolean setPos = false;
private void newPosition(){
destx = rdm.nextInt(963);
desty = rdm.nextInt(500);
//System.out.println(destx + " " + desty);
}
private void move(){
if(x > destx) x-=3;
if(y > desty) y-=3;
if(x < destx) x+=3;
if(y < desty) y+=3;
// if(x >= )
}
private void setPos(){
if(!setPos){
x = rdm.nextInt(500);
y = rdm.nextInt(100);
setPos = true;
}
}
public void update(){
setPos();
move();
if(counter > rdm.nextInt(20000)){
newPosition();
counter = 0;
}
counter++;
}
public void render(Screen screen){
sprite = Sprite.enemyjet;
screen.renderMob(x, y, sprite);
}
}
Bullet Class:
public class Bullet {
private Sprite sprite;
private boolean removed = false;
public int y = 0, x = 0;
public Bullet(int x, int y){
this.x = x;
this.y = y;
}
public boolean isRemoved(){
return removed;
}
public void update(){
y -= 15;
}
public void render(Screen screen){
sprite = Sprite.jetbullet;
screen.drawBullet(x, y, sprite);
}
}
Player Class:
public class Player extends Mob {
public List<Bullet> bullets = new ArrayList<Bullet>();
private Keyboard input;
private Sprite sprite;
private int counter = 0;
private int fireRate = 4;
public Player(Keyboard input){
this.input = input;
}
public void update(){
int xa = 0, ya = 0;
if(input.up) ya=-7;
if(input.down) ya =+7;
if(input.left) xa=-7;
if(input.right) xa=+7;
if(!input.up && !input.down && !input.left && !input.right)
intensity = 0; else intensity = 8;
move(xa, ya);
if(input.shoot && counter > fireRate){
bullet = new Bullet(x, y);
bullets.add(bullet);
counter = 0;
}
if(bullets.size() > 0){
for(int i = 0; i < bullets.size(); i++){
bullets.get(i).update();
if(bullets.get(i).y < 0){
bullets.remove(i);
}
}
}
counter++;
}
public void render(Screen screen){
sprite = Sprite.jet;
if(bullets.size()>0)
for(int i = 0; i < bullets.size(); i++){
bullets.get(i).render(screen);
}
screen.renderMob(x, y, sprite);
screen.setIntensity(intensity);
}
}
Added all classes Player, EnemyJet and Bullet.
you could go through all bullets and check if they have the same position as the enemyjet and implement a method in Mob that compares them if you will use the comparison repeatedly. Or you just do the compare yourself in your driver class that controls both during runtime, e.g. the main() or where the events are caught and synchronized and presented on screen.
Related
So I have an object in Java with a sprite associated to it. I also have an array of 4 different PImages, and I want to gradually change the sprite of that object into each of the PImages in that array (technically “animating” the sprite"), and I want each sprite to last for 0.5 seconds.
Can anyone help me with this?
Here is my approach. "Sprites" is the array containing the 4 images, brickwall is the object, and the event that triggers the sprite change is when a fireball hit the brickwall. I'll provide the code for the parts involved in the question.
for(int i = 0; i < this.fireballs.size(); i++){
//detect collision between fireball and wall
for(int b = 0; b < this.brickwalls.size(); b++){
if((this.fireballs.get(i).getX() <= this.brickwalls.get(b).getX()+10 & this.fireballs.get(i).getX() >= this.brickwalls.get(b).getX()-10) &&
(this.fireballs.get(i).getY() <= this.brickwalls.get(b).getY()+10 & this.fireballs.get(i).getY() >= this.brickwalls.get(b).getY()-10)){
if(this.brickwalls.get(b).counter == 0){
this.brickwalls.get(b).setSprite(wall.sprites[0]);
}
if(this.brickwalls.get(b).counter == 1){
this.brickwalls.get(b).setSprite(wall.sprites[1]);
}
if(this.brickwalls.get(b).counter == 2){
this.brickwalls.get(b).setSprite(wall.sprites[2]);
}
if(this.brickwalls.get(b).counter == 3){
this.brickwalls.get(b).setSprite(wall.sprites[3]);
}
this.fireballs.remove(i);
this.brickwalls.get(b).Exist = false;
//this.brickwalls.remove(b);
if(i == this.fireballs.size()){
break;
}
if(b == this.brickwalls.size()){
break;
}
}
}
}
Here is the wall class. Brickwall is an extension to wall.
package gremlins;
import processing.core.PImage;
import processing.core.PApplet;
public abstract class wall extends PApplet {
protected int x;
protected int y;
protected PImage sprite;
protected int size;
protected boolean Exist = true;
protected int switchTime = 1000;
protected int startTime = 0;
public int savedTime = millis();
public int counter = 0;
public static PImage[] sprites = new PImage[4];
public wall(int x, int y){
this.x = x;
this.y = y;
//load sprites into array
}
public void setSprite(PImage sprite) {
this.sprite = sprite;
}
public void draw(PApplet app){
app.image(this.sprite, this.x, this.y);
if(this.Exist = false){
if(millis() - startTime > 500){
counter++;
startTime = millis();
}
}
}
public int getX(){
return this.x;
}
public int getY(){
return this.y;
}
public void tick(){
}
}
package gremlins;
import processing.core.PImage;
import processing.core.PApplet;
public class brickwall extends wall {
public PImage sprite;
protected PImage[] destroyed = new PImage[4];
public brickwall(int x, int y){
super(x, y);
}
}
I am making a game with android. The player is a rectangle that has to jump over obstacles. When i jump i decrease the height and the y coordinates. When i run the game the rectangle is jumping but when i try to jump over an obstacle its still hitting it. So i think i forget to change a value but i have no idea what value. Sorry for my bad english and i am a beginner at coding.
This is my Player class:
package com.example.niek.speelveld;
import android.graphics.Canvas;
import android.graphics.Paint;
/**
* Created by Niek on 15-8-2017.
*/
public class Player extends GameObject {
private int score;
private boolean up;
private boolean playing;
private long startTime;
private int h = 0;
private boolean jump;
public Player(int x , int y){
super.x = x;
super.y = y;
width = 100;
height = GamePanel.HEIGHT;
score = 0;
startTime = System.nanoTime();
}
public void setUp(boolean b){up = b;}
public void update(){
long elapsed = (System.nanoTime()-startTime)/1000000;
if(elapsed>100){
score++;
startTime = System.nanoTime();
}
if(up && h == 0){
jump = true;
up = false;
}
if (jump) {
if (h < 120) {
h = h + 7;
height = height - 7;
y = y - 7;
} else {
jump = false;
}
} else {
if (h > 0) {
h = h - 7;
height = height + 7;
y = y + 7;
}
}
}
public void draw(Canvas canvas){
Paint myPaint = new Paint();
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setStrokeWidth(7);
canvas.drawRect(x, y, width + x, height, myPaint );
myPaint.setStrokeWidth(1);
canvas.drawText("HIGHSCORE " + score, GamePanel.WIDTH - 100 , 0+myPaint.getTextSize(), myPaint);
}
public int getScore(){return score;}
public boolean getPlaying(){return playing;}
public void setPlaying(boolean b){playing = b;}
//public void resetScore(){score = 0;}
public boolean getJump() {
return jump;
}
}
And in my Gamepanel class i use these 2 methods. When i call the class obstacle.get(i).update(); its only updating the x value so its moving towards the player.
public void update(){
if(player.getPlaying()) {
bg.update();
player.update();
//Add obstacles with timer
long obstacleElapsed = (System.nanoTime()-obstacleStartTime)/1000000;
if(obstacleElapsed >(2000 - player.getScore()/4)){
obstacles.add(new Obstacle(BitmapFactory.decodeResource(getResources(), R.drawable.rsz_spike1), WIDTH + 10, HEIGHT - 51, 14, 51, player.getScore()));
//reset timer
obstacleStartTime = System.nanoTime();
}
}
//Loop through every obstacle and check collision
for(int i = 0; i<obstacles.size(); i++){
obstacles.get(i).update();
if (collision(obstacles.get(i), player)) {
obstacles.remove(i);
player.setPlaying(false);
Intent intent = new Intent(c, Result.class);
intent.putExtra("SCORE", player.getScore());
c.startActivity(intent);
break;
}
//Remove obstacles that are out of the screen
if (obstacles.get(i).getX() < -100) {
obstacles.remove(i);
break;
}
}
}
public boolean collision(GameObject o, GameObject p){
if(Rect.intersects(o.getRectangle(), p.getRectangle())){
return true;
}
return false;
}
#Override
public void draw(Canvas canvas){
//Get Width and Height from screen
final float scaleFactorX = (float)getWidth()/WIDTH;
final float scaleFactorY = (float)getHeight()/HEIGHT;
if(canvas!=null) {
final int savedState = canvas.save();
canvas.scale(scaleFactorX, scaleFactorY);
bg.draw(canvas);
player.draw(canvas);
//Draw obstacles
for(Obstacle o : obstacles ){
o.draw(canvas);
}
canvas.restoreToCount(savedState);
}
}
And finally the Player and the Obstacle class extends Gameobject where i have the getRectangle method.
public Rect getRectangle(){
return new Rect(x, y, x+width, y+height);
}
I making a game in Android Studio with Java. I am having an issue where my collectible keeps re-spawning in the same position after the player has collected it. I would like for it to re-spawn at random positions on the screen. How can I do this?
The collectible is a fuel can.
Here is the fuel can collectible class
Fuel.java
public class Fuel extends GameObject {
public Fuel(Bitmap res, int w, int h, int numFrames) {
x = GamePanel.WIDTH + 5000;
y = GamePanel.HEIGHT / 2;
dy =(random.nextInt()*(GamePanel.HEIGHT - (maxBorderHeight* 2)+maxBorderHeight));
dx = +GamePanel.MOVESPEED;
height = h;
width = w;
Bitmap[] image = new Bitmap[numFrames];
spritesheet = res;
for (int i = 0; i < image.length; i++)
{
image[i] = Bitmap.createBitmap(spritesheet, 0, i*height, width, height);
}
animation.setFrames(image);
animation.setDelay(100-dx);
animation.update();
}
public void update()
{
if (x < 0) {
reset();
}
x += dx;
dx = dx- 1;
if (dx <= -15) {
dx = -15;
}
animation.update();
}
public void draw(Canvas canvas)
{
try {
canvas.drawBitmap(animation.getImage(),x,y,null);
}catch (Exception e){}
}
public void reset(){
x = GamePanel.WIDTH + 5000;
y = GamePanel.HEIGHT/2 ;
dy = (random.nextInt()*(GamePanel.HEIGHT - (maxBorderHeight* 2)+maxBorderHeight));
dx = +GamePanel.MOVESPEED;
}
public void fuelCollected(){
reset();
}
}
GamePanel.java
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback
{
private Fuel fuel;
#Override
public void surfaceCreated(SurfaceHolder holder){
fuel = new Fuel(BitmapFactory.decodeResource(getResources(), R.drawable.fuel),40,40,1);
}
public void update()
{
fuel.update();
if(collectFuel(player,fuel)){
distance +=100;
}
public boolean collectFuel(GameObject player, GameObject fuel){
if(Rect.intersects(player.getRectangle(),fuel.getRectangle()))
{
fuelCollected();
return true;
}
return false;
}
public void fuelCollected(){fuel.fuelCollected();}
}
#Override
public void draw(Canvas canvas){
// draw fuel can
fuel.draw(canvas);
}
}
Change Fuel reset() method to something like this:
public void reset() {
x = random.nextInt(GamePanel.WIDTH);
y = random.nextInt(GamePanel.HEIGHT);
dy = (random.nextInt()*(GamePanel.HEIGHT - (maxBorderHeight* 2)+maxBorderHeight));
dx = +GamePanel.MOVESPEED;
}
Assuming that x, y are integer variables x will be a random integer between 0 and GamePanel.WIDTH and y a random integer between 0 and GamePanel.HEIGHT.
Why do you add 5000 to the GamePanel.WIDTH ?
I am making a 2D game in Libgdx and when I try to make a player shoot every X seconds it crashes and that happens only if I call addBullet() inside a timer.
Here is code for Controller.class:
public class Controller {
private LinkedList<Bullet> b = new LinkedList<Bullet>();
private Bullet tempBullet;
private LinkedList<Zombie> z = new LinkedList<Zombie>();
private Zombie tempZombie;
private API api;
private Player p;
private World w;
public void create() {
api = new API();
w = new World();
p = new Player(100, 40);
Timer t = new Timer( );
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// Crashes when this is executed
addBullet(new Bullet(p.getX() + p.getTex().getWidth(), p.getY() + p.getTex().getHeight()));
}
}, 500,2500);
}
public void tick() {
p.tick();
for(int i = 0; i < b.size(); i++){
tempBullet = b.get(i);
tempBullet.tick();
}
for(int i = 0; i < z.size(); i++){
tempZombie = z.get(i);
tempZombie.tick();
for(int j = 0; j < b.size(); j++){
tempBullet = b.get(j);
if(api.getCollisionBox(tempZombie.getX(), tempZombie.getY(), tempZombie.getTex().getWidth(), tempZombie.getTex().getHeight(), tempBullet.getX(), tempBullet.getY(), 10, 10)){
tempZombie.damage();
b.remove(tempBullet);
if(tempZombie.getHealth() <= 0){
z.remove(tempZombie);
}
}
}
}
}
public void render() {
w.render(); // Mora biti na pocetku ove funkcije
p.render();
for(int i = 0; i < b.size(); i++){
tempBullet = b.get(i);
tempBullet.render();
}
for(int i = 0; i < z.size(); i++){
tempZombie = z.get(i);
tempZombie.render();
}
}
public void dispose() {
w.dispose();
p.dispose();
for(int i = 0; i < b.size(); i++){
tempBullet = b.get(i);
tempBullet.dispose();
}
for(int i = 0; i < z.size(); i++){
tempZombie = z.get(i);
tempZombie.dispose();
}
}
public void keyInput() {
//if(Gdx.input.isButtonPressed(Input.Keys.W))
}
public void mouseInput() {
//if(Gdx.input.isButtonPressed(Input.Buttons.LEFT))
if(Gdx.input.isTouched())
addBullet(new Bullet(p.getX() + p.getTex().getWidth(), p.getY() + p.getTex().getHeight()));
}
public void addBullet(Bullet block){
b.add(block);
}
public void removeBullet(Bullet block){
b.remove(block);
}
public void addZombie(Zombie block){
z.add(block);
}
public void removeZombie(Zombie block){
z.remove(block);
}
}
Here is the code for the bullet.class:
public class Bullet {
private Texture tex;
private SpriteBatch batch;
private int x;
private int y;
public Bullet(int x, int y){
this.x = x;
this.y = y;
batch = new SpriteBatch();
tex = new Texture(Gdx.files.internal(("bullet.png")));
}
public void tick(){
x += 10;
}
public void render(){
batch.begin();
batch.draw(tex, x, y, 100, 100);
batch.end();
}
public void dispose() {
tex.dispose();
batch.dispose();
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Without seeing the full exception, my guess is that there might be something wrong with the loading of the image.
ps. Why the extra brackets?
tex = new Texture(Gdx.files.internal(("bullet.png")));
One set of brackets is enough:
tex = new Texture(Gdx.files.internal("bullet.png"));
I have question about random generation of sprite sheet tiles in java. Whenever I try to use a for loop the random generation changes every millisecond or faster. I am very confused and have no idea where to start from here. If anyone can come up with some easy code for a begginer to grasp the concept of random generation!
Here is the code I am working with for generating a flat map /
public class Map {
Random random = new Random();
public static int mapxDirection;
public static int mapx = 1;
public static int bgSpeed = 20;
public static int grass = 16;
public static int dirt = 0;
public static int stone = 1;
public static int waterup = 2;
public static int waterside = 18;
public static int glass = 17;
public static int chicken = 32;
public static int steak = 33;
public static int mapSpeed = 3;
public static BufferedImage[] sprites;
public void renderMap(Graphics g) {
final int width = 32;
final int height = 32;
final int rows = 16;
final int cols = 16;
sprites = new BufferedImage[rows * cols];
BufferedImage spritesheet = null;
try {
spritesheet = ImageIO.read(new File("res/SpriteSheet.png"));
} catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
sprites[(i * cols) + j] = spritesheet.getSubimage(i * width, j
* height, width, height);
}
}
for (int i = 0; i < 2000; i += 32) {
g.drawImage(sprites[grass], Map.mapx + i, 259, null);
}
for (int i = 0; i < 2000; i += 32) {
for (int j = 291; j <= 508; j += 32) {
g.drawImage(sprites[dirt], Map.mapx + i, j, null);
}
}
for (int i = 0; i < 2000; i += 32) {
for (int j = 508; j <= 540; j += 32) {
g.drawImage(sprites[stone], Map.mapx + i, j - 3, null);
}
}
}
}
There are multiple ways this can be done, it also depends on what type on random generation you want to achieve for example, do you what to completely randomize every tile or do you what to load random chunks. The popular game Minecraft uses the method of random chuck generation.
If your new to game programming, i recommend checking out RealTutsGML Game Programming Tutorials. He teaches you a easy and good way of loading in sprite sheets and also teaches you how to load in and create a level in paint. All though he is making a platformer, you can easily convert the same method into a top down game.
Here is how i would go about creating a random generation map. First i would create a abstract class called GameObject. Every object you make will extend this class.
public abstract class GameObject {
protected float x, y;
protected ObjectId id;
protected float velX= 0, velY = 0;
protected boolean falling = true;
protected boolean jumping = false;
public GameObject(float x, float y, ObjectId id) {
this.x = x;
this.y = y;
this.id = id;
}
public abstract void tick(LinkedList<GameObject> object);
public abstract void render(Graphics g);
public abstract Rectangle getBounds();
public float getX() { return x; }
public float getY() { return y; }
public float getVelX() { return velX; }
public float getVelY() { return velY; }
public boolean isFalling() { return falling; }
public boolean isJumping() { return jumping; }
public void setX(float x) { this.x = x; }
public void setY(float y) { this.y = y; }
public void setVelX(float velX) { this.velX = velX; }
public void setVelY(float velY) { this.velY = velY; }
public void setFalling(boolean falling) { this.falling = falling; }
public void setJumping(boolean jumping) { this.jumping = jumping; }
public ObjectId getId() { return id; }
}
For example if i want to make a object called Block, i would create a class called Block and extends GameObject like this.
public class Block extends GameObject {
private boolean animate = true;
Texture tex = Game.getInstance();
private int type;
public Block(float x, float y, int type, ObjectId id) {
super(x, y, id);
this.type = type;
}
public void tick(LinkedList<GameObject> object) {
bAnimate.runAnimation();
}
public void render(Graphics g) {
if (type == 0) g.drawImage(tex.red_block[0], (int)x, (int)y, null); // Red Block
if (type == 1) g.drawImage(tex.green_block[0], (int)x, (int)y, null); // Blue Block
if (type == 2) g.drawImage(tex.blue_block[0], (int)x, (int)y, null); // Green Block
if (type == 3) g.drawImage(tex.yellow_block[0], (int)x, (int)y, null); // Yellow Block
if (type == 4) g.drawImage(tex.orange_block[0], (int)x, (int)y, null); // Orange Block
if (type == 5) g.drawImage(tex.pink_block[0], (int)x, (int)y, null); // Pink Block
}
public Rectangle getBounds() {
return new Rectangle((int)x, (int)y, 32, 32);
}
}
I then create a LinkedList like this. An also create 2 methods for adding and removing objects for the list.
protected LinkedList<GameObject> object = new LinkedList<GameObject>();
public void addObject(GameObject object) {
this.object.add(object);
}
public void remove(GameObject object) {
this.object.remove(object);
}
I would then simply add objects to the list like this.
addObject(new Block(x * 32, y * 32, random.nextInt(6), ObjectId.Block));
Sense this post is getting kinda big i will leave the rest to you, if you like i can see you the source code of the project i am using. This is also the same method that "RealTutsGML" uses in his tutorials.
I see that you and using Map.mapx instead of that just write the variable mapx no need for the Map. Also your data should always be private or protected. I also recommend making a variable that holds your map size like this.
private static int mapSize = 2000;
It is just so that if you want to change the map size you don't have to replace more than one number.
I hope this helps you out.
Here is a list of java programming books.