Player should win when all objects are collected - scripting

I have a simple game where the player needs to collect 4 game objects within 30 sec. Now I already created the timer, so I need to let the game know that if all game objects are collected under the time limit the player wins.
This is my code so far:
using UnityEngine;
using System.Collections;
public class GameState : MonoBehaviour
{
public static int count = 0;
public float seconds = 30;
public float minutes = 0;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if (seconds <= 0)
{
seconds = 30;
if (minutes >= 1)
{
minutes -- ;
}
else
{
minutes = 0;
seconds = 0;
GameObject.Find("TimerText").guiText.text = minutes.ToString("f0") + ":0" + seconds.ToString("f0");
}
}
else
{
seconds -= Time.deltaTime;
}
if (Mathf.Round(seconds) <=9)
{
GameObject.Find("TimerText").guiText.text = minutes.ToString("f0") + ":0" + seconds.ToString("f0");
}
else
{
GameObject.Find("TimerText").guiText.text = minutes.ToString("f0") + ":" + seconds.ToString("f0");
}
if(count >= 1)
{
print("You Won!");
}
}
void OnTriggerEnter(Collider collide)
{
if (collide.transform.tag == "Cube")
{
count = count + 1;
Destroy (collide.gameObject);
}
}
}
Note: cube is one of the game object that needs to be picked up.

you could interrupt the game or show a victory menu or something when you have all the cubes collected
void Update ()
{
bool cubescollected = false;
if(cubescollected == 4)
{
ShowVictoryOrSomething();
cubescollected = true
}
if(cubescollected == true)
return;
... your timer code
}
good luck and happy coding

Related

JavaFx Problem with Service and Task with different Parameters and multiple calls

i need to create a Service and a Task to calculate the Mandelbrot and JuliaSet.
The calculation is working pretty good and now we need to give it into a Service and call it inside the task.
I have now the Problem, that every Time the task is executed, the Parameters are different.
I wrote a little Setter Function to parse those Arguments to the Service first.
But i'm not sure if this is the right Way?!
I'm also not sure how to correctly call the service in the main Function?
Now it works like this:
First time the service is executed, everything seems to work, but when i call it a secound Time, nothing seems to happen.....
Just to make sure: A Service can execute the Task multiple Times at the same Time?
Is it also posible with different Parameters?
Code Task:
private MandelbrotRenderOptions mandelbrot;
private JuliaRenderOptions juliaset;
private Canvas leftCanvas;
private Canvas rightCanvas;
//Constructor
public RenderTask(Canvas leftCanvas, Canvas rightCanvas) {
this.leftCanvas = leftCanvas;
this.rightCanvas = rightCanvas;
}
public void setOptions(MandelbrotRenderOptions mandelbrot, JuliaRenderOptions juliaset) {
this.mandelbrot = mandelbrot;
this.juliaset = juliaset;
}
#Override
protected Void call() throws Exception {
try {
System.out.println("HALLO SERVICE");
// instances for rendering the left canvas [pixel.data -> PixelWriter -> WritableImage -> GraphicsContext -> Canvas]
// creates an writable image which contains the dimensions of the canvas
WritableImage wimLeftCanvas = new WritableImage((int) leftCanvas.getWidth(), (int) leftCanvas.getHeight());
// instance which can write data into the image (instance above)
PixelWriter pwLeftCanvas = wimLeftCanvas.getPixelWriter();
// instance which fills the canvas
GraphicsContext gcLeftCanvas = leftCanvas.getGraphicsContext2D();
// instances for rendering the right canvas [pixel.data -> PixelWriter -> WritableImage -> GraphicsContext -> Canvas]
WritableImage wimRightCanvas = new WritableImage((int) rightCanvas.getWidth(), (int) rightCanvas.getHeight());
PixelWriter pwRight = wimRightCanvas.getPixelWriter();
GraphicsContext gcRightCanvas = rightCanvas.getGraphicsContext2D();
gcLeftCanvas.clearRect(0, 0, leftCanvas.getWidth(), leftCanvas.getHeight());
//Pixel[][] pixels; // contains pixel data for rendering canvas
// instances for logging the rendered data
SimpleImage simpleImageLeftCanvas = new SimpleImage((int) leftCanvas.getWidth(), (int) leftCanvas.getHeight());
SimpleImage simpleImageRightCanvas = new SimpleImage((int) rightCanvas.getWidth(), (int) rightCanvas.getHeight());
short dataSimpleImage[] = new short[3]; // contains pixel data for logging rendered data
// fills left canvas (mandelbrot) PixelWriter instance with data
Pixel[][] pixels = mandelbrot.setAllPixels();
FractalLogger.logRenderCall(mandelbrot);
for (int y = 0; y < (int) leftCanvas.getHeight(); y++) {
for (int x = 0; x < (int) leftCanvas.getWidth(); x++) {
// parses color data to PixelWriter instance
Color color = Color.rgb(pixels[y][x].getRed(), pixels[y][x].getGreen(), pixels[y][x].getBlue());
pwLeftCanvas.setColor(x, y, color);
for (int depth = 0; depth < 3; depth++) {
if (depth == 0) {
dataSimpleImage[depth] = pixels[y][x].getRed();
} else if (depth == 1) {
dataSimpleImage[depth] = pixels[y][x].getGreen();
} else {
dataSimpleImage[depth] = pixels[y][x].getBlue();
}
}
try {
simpleImageLeftCanvas.setPixel(x, y, dataSimpleImage); // because data must not be null
} catch (InvalidDepthException e) {
e.printStackTrace();
}
}
}
// logs that rendering of mandelbrot is finished
FractalLogger.logRenderFinished(FractalType.MANDELBROT, simpleImageLeftCanvas);
// fills left canvas (juliaset) PixelWriter instance with data
pixels = juliaset.setAllPixels();
FractalLogger.logRenderCall(mandelbrot);
for (int y = 0; y < (int) rightCanvas.getHeight(); y++) {
for (int x = 0; x < (int) rightCanvas.getWidth(); x++) {
// pareses color to PixelWriter instance
Color color = Color.rgb(pixels[y][x].getRed(), pixels[y][x].getGreen(), pixels[y][x].getBlue());
pwRight.setColor(x, y, color);
for (int depth = 0; depth < 3; depth++) {
if (depth == 0) {
dataSimpleImage[depth] = pixels[y][x].getRed();
} else if (depth == 1) {
dataSimpleImage[depth] = pixels[y][x].getGreen();
} else {
dataSimpleImage[depth] = pixels[y][x].getBlue();
}
}
try {
simpleImageRightCanvas.setPixel(x, y, dataSimpleImage); // because data must not be null
} catch (InvalidDepthException e) {
e.printStackTrace();
}
}
}
// logs that rendering of juliaset is finished
FractalLogger.logRenderFinished(FractalType.JULIA, simpleImageRightCanvas);
// writes data from WriteableImage instance to GraphicsContext instance, which finally parses renders it into the canvas
gcLeftCanvas.drawImage(wimLeftCanvas, 0, 0);
FractalLogger.logDrawDone(FractalType.MANDELBROT);
gcRightCanvas.drawImage(wimRightCanvas, 0, 0);
FractalLogger.logDrawDone(FractalType.JULIA);
return null;
} catch (Exception e) {
System.out.println("ERROR");
System.out.println(e);
return null;
}
}
#Override
protected void cancelled()
{
super.cancelled();
updateMessage("The task was cancelled.");
}
#Override
protected void failed()
{
super.failed();
updateMessage("The task failed.");
}
#Override
public void succeeded()
{
super.succeeded();
updateMessage("The task finished successfully.");
} ```
And i call it like this in the main:
``` Service service = new Service() {
#Override
protected Task createTask() {
return new RenderTask(leftCanvas, rightCanvas);
}
};
task.setOptions(mandelbrot, juliaset);
service.restart(); ```

Libgdx null pointer 2d jump and run game

I want to implement in my 2d jump and run game that my player can shoot but I always get a null pointer exception.
Does anyone know why?
In this class I check for input:
public class InputIngame implements InputProcessor {
Player player;
public void handleInput(){
//control our player using immediate impulses
if (Gdx.input.isKeyJustPressed(Input.Keys.W) && PlayScreen.player.b2body.getLinearVelocity().y == 0)
PlayScreen.player.b2body.applyLinearImpulse(new Vector2(0, 6f), PlayScreen.player.b2body.getWorldCenter(), true);
if (Gdx.input.isKeyPressed(Input.Keys.D) && PlayScreen.player.b2body.getLinearVelocity().x <= 2)
PlayScreen.player.b2body.applyLinearImpulse(new Vector2(0.2f, 0), PlayScreen.player.b2body.getWorldCenter(), true);
if (Gdx.input.isKeyPressed(Input.Keys.A) && PlayScreen.player.b2body.getLinearVelocity().x >= -2)
PlayScreen.player.b2body.applyLinearImpulse(new Vector2(-0.2f, 0), PlayScreen.player.b2body.getWorldCenter(), true);
if (Gdx.input.isKeyPressed(Input.Keys.D) && Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) && PlayScreen.player.b2body.getLinearVelocity().x > 1)
PlayScreen.player.b2body.setLinearVelocity(1, PlayScreen.player.b2body.getLinearVelocity().y);
if (Gdx.input.isKeyPressed(Input.Keys.A) && Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) && PlayScreen.player.b2body.getLinearVelocity().x < -1)
PlayScreen.player.b2body.setLinearVelocity(-1, PlayScreen.player.b2body.getLinearVelocity().y);
if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE))
player = new Player();
player.fire();
}
in my screen class I draw the fireball:
#Override
public void render(float delta) {
//separate our update logic from render
update(delta);
//Clear the game screen with Black
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//render our game map
renderer.render();
if (player.isDead == true)
player.die();
player.draw(runner.batch);
//renderer our Box2DDebugLines
b2dr.render(world, gamecam.combined);
runner.batch = new SpriteBatch();
runner.batch.setProjectionMatrix(gamecam.combined);
runner.batch.begin();
player.draw(runner.batch);
runner.batch.end();
if (TimeUtils.timeSinceNanos(startTime) > 1000000000) {
startTime = TimeUtils.nanoTime();
}
Gdx.app.log("FPSLogger", "fps: " + Gdx.graphics.getFramesPerSecond());
}
In my player class I set my variables:
private PlayScreen screen;
private Array<FireBall> fireballs;
And init them:
public Player(PlayScreen screen){
//initialize default values
runner = new HardwareRunner();
this.screen = screen;
fireballs = new Array<FireBall>();
And this method is execudet in the render method:
public void update(float dt){
//update our sprite to correspond with the position of our Box2D body
setPosition(b2body.getPosition().x - getWidth() / 2, b2body.getPosition().y - getHeight() / 2);
//update sprite with the correct frame depending on marios current action
setRegion(getFrame(dt));
for(FireBall ball : fireballs) {
ball.update(dt);
}
}
And there are also these methods:
public void fire(){
fireballs.add(new FireBall(screen, b2body.getPosition().x, b2body.getPosition().y, runningRight ? true : false));
}
public void draw(Batch batch){
super.draw(batch);
for(FireBall ball : fireballs)
ball.draw(batch);
}
And then theres my fireball class:
public class FireBall extends Sprite {
PlayScreen screen;
World world;
Array<TextureRegion> frames;
Animation fireAnimation;
float stateTime;
boolean destroyed;
boolean setToDestroy;
boolean fireRight;
Body b2body;
public FireBall(PlayScreen screen, float x, float y, boolean fireRight){
this.fireRight = fireRight;
this.screen = screen;
this.world = screen.getWorld();
frames = new Array<TextureRegion>();
for(int i = 0; i < 4; i++){
frames.add(new TextureRegion(screen.getAtlas().findRegion("fireball"), i * 8, 0, 8, 8));
}
fireAnimation = new Animation(0.2f, frames);
setRegion(fireAnimation.getKeyFrame(0));
setBounds(x, y, 6 / HardwareRunner.PPM, 6 / HardwareRunner.PPM);
defineFireBall();
}
public void defineFireBall(){
BodyDef bdef = new BodyDef();
bdef.position.set(fireRight ? getX() + 12 /HardwareRunner.PPM : getX() - 12 /HardwareRunner.PPM, getY());
bdef.type = BodyDef.BodyType.DynamicBody;
if(!world.isLocked())
b2body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
CircleShape shape = new CircleShape();
shape.setRadius(3 / HardwareRunner.PPM);
fdef.filter.categoryBits = HardwareRunner.PROJECTILE_BIT;
fdef.filter.maskBits = HardwareRunner.GROUND_BIT |
HardwareRunner.BRICK_BIT |
HardwareRunner.OBJECT_BIT;
fdef.shape = shape;
fdef.restitution = 1;
fdef.friction = 0;
b2body.createFixture(fdef).setUserData(this);
b2body.setLinearVelocity(new Vector2(fireRight ? 2 : -2, 2.5f));
}
public void update(float dt){
stateTime += dt;
setRegion(fireAnimation.getKeyFrame(stateTime, true));
setPosition(b2body.getPosition().x - getWidth() / 2, b2body.getPosition().y - getHeight() / 2);
if((stateTime > 3 || setToDestroy) && !destroyed) {
world.destroyBody(b2body);
destroyed = true;
}
if(b2body.getLinearVelocity().y > 2f)
b2body.setLinearVelocity(b2body.getLinearVelocity().x, 2f);
if((fireRight && b2body.getLinearVelocity().x < 0) || (!fireRight && b2body.getLinearVelocity().x > 0))
setToDestroy();
}
public void setToDestroy(){
setToDestroy = true;
}
public boolean isDestroyed(){
return destroyed;
}
}
But if I try to start the game I get this error:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at de.tobls.hardwarerunner.Input.InputIngame.handleInput(InputIngame.java:30)
at de.tobls.hardwarerunner.Screens.PlayScreen.update(PlayScreen.java:109)
at de.tobls.hardwarerunner.Screens.PlayScreen.render(PlayScreen.java:130)
at com.badlogic.gdx.Game.render(Game.java:46)
at de.tobls.hardwarerunner.HardwareRunner.render(HardwareRunner.java:71)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
line 30 is player.fire();
line 109 is input.handleInput();
line 130 is update(delta);
and line 71 is update(delta); in my main class
I hope anyone can help me!
i think your problem is you forget brakets in "if" condition try this :
if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
player = new Player();
player.fire();
}
good luck ;
if any trouble leave a comment ;)

java.lang.NullPointerException in JApplet game

new guy to stack and to java.
to start off, here's my code,
AsteroidsGame.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.util.*;
public class AsteroidsGame extends JApplet implements Runnable, KeyListener {
Thread thread;
Dimension dim;
Image img;
Graphics g;
long endTime, startTime, framePeriod;
Ship ship;
boolean paused;
// True if the game is paused. Enter is the pause key
Shot[] shots;
int numShots;
boolean shooting;
Asteroid[] asteroids;
int numAsteroids;
double astRadius;
double minAstVel;
double maxAstVel;
int astNumHits;
int astNumSplit;
int level;
private AudioClip audioClip;
public void init() {
resize(500, 500);
shots = new Shot[41];
numAsteroids = 0;
level = 0;
astRadius = 60;
minAstVel = .5;
maxAstVel = 5;
astNumHits = 3;
astNumSplit = 2;
endTime = 0;
startTime = 0;
framePeriod = 25;
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
dim = getSize();
img = createImage(dim.width, dim.height);
g = img.getGraphics();
thread = new Thread(this);
thread.start();
URL urlAudioClip = getClass().getResource("audio/minorcircuit.wav");
audioClip = Applet.newAudioClip(urlAudioClip);
audioClip.loop();
}
public void start() {
audioClip.loop();
}
public void stop() {
audioClip.stop();
}
public void setUpNextLevel() {
level++;
ship = new Ship(250, 250, 0, .35, .98, .1, 12);
numShots = 0;
paused = false;
shooting = false;
asteroids = new Asteroid[level * (int)Math.pow(astNumSplit, astNumHits - 1) + 1];
numAsteroids = level;
for(int i = 0; i < numAsteroids; i++) {
asteroids[i] = new Asteroid(Math.random() * dim.width, Math.random() * dim.height, astRadius, minAstVel, maxAstVel, astNumHits, astNumSplit);
}
}
public void paint(Graphics gfx) {
g.setColor(Color.black);
g.fillRect(0, 0, 500, 500);
for(int i = 0; i < numShots; i++) {
shots[i].draw(g);
}
for(int i = 0; i < numAsteroids; i++) {
asteroids[i].draw(g);
}
ship.draw(g);
//draw the ship
g.setColor(Color.cyan);
g.drawString("Level " + level, 20, 20);
gfx.drawImage(img, 0, 0, this);
}
public void update(Graphics gfx) {
paint(gfx);
}
public void run() {
for(;;) {
startTime = System.currentTimeMillis();
//start next level when all asteroids are destroyed
if(numAsteroids <= 0) {
setUpNextLevel();
}
if(!paused) {
ship.move(dim.width, dim.height);
//move the ship
for(int i = 0; i < numShots; i++) {
shots[i].move(dim.width, dim.height);
if(shots[i].getLifeLeft() <= 0) {
deleteShot(i);
i--;
}
}
updateAsteroids();
if(shooting && ship.canShoot()) {
//add a shot on to the array
shots[numShots] = ship.shoot();
numShots++;
}
}
repaint();
try {
endTime = System.currentTimeMillis();
if(framePeriod - (endTime - startTime) > 0) {
Thread.sleep(framePeriod - (endTime - startTime));
}
}
catch(InterruptedException e) {
}
}
}
private void deleteShot(int index) {
//delete shot and move all shots after it up in the array
numShots--;
for(int i = index; i < numShots; i++) {
shots[i] = shots[i + 1];
shots[numShots] = null;
}
}
private void deleteAsteroid(int index) {
//delete asteroid and shift ones after it up in the array
numAsteroids--;
for(int i = index; i < numAsteroids; i++) {
asteroids[i] = asteroids[i + 1];
asteroids[numAsteroids] = null;
}
}
private void addAsteroid(Asteroid ast) {
//adds asteroid in at end of array
asteroids[numAsteroids] = ast;
numAsteroids++;
}
private void updateAsteroids() {
for(int i = 0; i < numAsteroids; i++) {
// move each asteroid
asteroids[i].move(dim.width, dim.height);
//check for collisions with the ship
if(asteroids[i].shipCollision(ship)) {
level--;
//restart this level
numAsteroids = 1;
return;
}
//check for collisions with any of the shots
for(int j = 0; j < numShots; j++) {
if(asteroids[i].shotCollision(shots[j])) {
//if the shot hit an asteroid, delete the shot
deleteShot(j);
//split the asteroid up if needed
if(asteroids[i].getHitsLeft() > 1) {
for(int k = 0; k < asteroids[i].getNumSplit(); k++) {
addAsteroid(
asteroids[i].createSplitAsteroid(
minAstVel, maxAstVel));
}
}
//delete the original asteroid
deleteAsteroid(i);
j=numShots;
i--;
}
}
}
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER) {
if(!ship.isActive() && !paused) {
ship.setActive(true);
}
else {
paused = !paused;
//enter is the pause button
if(paused) {
//grays out the ship if paused
ship.setActive(false);
}
else {
ship.setActive(true);
}
}
}
else if(paused || !ship.isActive()) {
return;
}
else if(e.getKeyCode() == KeyEvent.VK_SPACE) {
ship.setAccelerating(true);
}
else if(e.getKeyCode() == KeyEvent.VK_LEFT) {
ship.setTurningLeft(true);
}
else if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
ship.setTurningRight(true);
}
else if(e.getKeyCode() == KeyEvent.VK_CONTROL) {
shooting=true;
}
else if(e.getKeyCode() == KeyEvent.VK_M) {
audioClip.stop();
}
else if(e.getKeyCode() == KeyEvent.VK_S) {
audioClip.loop();
}
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP) {
ship.setAccelerating(false);
}
else if(e.getKeyCode() == KeyEvent.VK_LEFT) {
ship.setTurningLeft(false);
}
else if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
ship.setTurningRight(false);
}
else if(e.getKeyCode() == KeyEvent.VK_CONTROL) {
shooting=false;
}
}
public void keyTyped(KeyEvent e) {
}
}
this is a "clone" of Asteroids. Some of you who have been around maybe a little longer than myself have probably played it in an arcade. Anyways, I wrote this for a final project in my Java course, but could never get to work completely. It starts up just fine, you can turn and shoot, but not move forward. I'm not worried about moving right now though. What happens after applet starts is music plays and an "asteroid" travels across the screen. If you shoot the asteroid or shoot 3 times in any direction, a thread exception occurs.
Exception in thread "Thread-3" java.lang.NullPointerException
at AsteroidsGame.updateAsteroids(AseroidsGame.java:161)
at AsteroidsGame.run(AsteroidsGame.java:115)
at java.lang.Thread.run(Thread.java:722)
Having looked around online has benefited me very little. Most of what I have learned was self taught and not as easy to wrap my head around. I'm not exactly sure what to do here to resolve this exception. In another thread on stack, it was mentioned to use an ArrayList because the array was not formerly declared with a size. Tinkered with that; never got it to work.
I need ideas/suggestions/criticism. I want to get this to work just so I can say I finished it.
other classes,
Asteroid.java
import java.awt.*;
public class Asteroid {
double x, y, xVelocity, yVelocity, radius;
int hitsLeft, numSplit;
public Asteroid(double x,double y,double radius,double minVelocity, double maxVelocity,int hitsLeft,int numSplit) {
this.x = x;
this.y = y;
this.radius = radius;
this.hitsLeft = hitsLeft;
this.numSplit = numSplit;
double vel = minVelocity + Math.random() * (maxVelocity - minVelocity);
double dir = 2 * Math.PI * Math.random();
xVelocity = vel * Math.cos(dir);
yVelocity = vel * Math.sin(dir);
}
public void move(int scrnWidth, int scrnHeight) {
x += xVelocity;
y += yVelocity;
if(x < 0 - radius) {
x += scrnWidth + 2 * radius;
}
else if(x > scrnWidth + radius) {
x -= scrnWidth + 2 * radius;
}
if(y < 0 - radius) {
y += scrnHeight + 2 * radius;
}
else if(y > scrnHeight + radius) {
y -= scrnHeight + 2 * radius;
}
}
public void draw(Graphics g) {
g.setColor(Color.gray);
g.fillOval((int)(x - radius + .5), (int)(y - radius + .5), (int)(2 * radius), (int)(2 * radius));
}
public Asteroid createSplitAsteroid(double minVelocity,double maxVelocity) {
return new Asteroid(x, y, radius / Math.sqrt(numSplit), minVelocity, maxVelocity, hitsLeft - 1, numSplit);
}
public boolean shipCollision(Ship ship) {
if(Math.pow(radius + ship.getRadius(), 2) > Math.pow(ship.getX() - x, 2) + Math.pow(ship.getY() - y, 2) && ship.isActive()) {
return true;
}
return false;
}
public boolean shotCollision(Shot shot) {
if(Math.pow(radius, 2) > Math.pow(shot.getX() - x, 2) + Math.pow(shot.getY() - y, 2)) {
return true;
}
return false;
}
public int getHitsLeft() {
return hitsLeft;
}
public int getNumSplit() {
return numSplit;
}
}
Ship.java
import java.awt.*;
public class Ship {
final double[] origXPts = {14,-10,-6,-10}, origYPts = {0,-8,0,8}, origFlameXPts = {-6,-23,-6}, origFlameYPts = {-3,0,3};
final int radius = 6;
double x, y, angle, xVelocity, yVelocity, acceleration, velocityDecay, rotationalSpeed;
//used for movement
boolean turningLeft, turningRight, accelerating, active;
int [] xPts, yPts, flameXPts, flameYPts;
//current location of ship
int shotDelay, shotDelayLeft;
//rate of fire
public Ship(double x, double y, double angle, double acceleration, double velocityDecay, double rotationalSpeed, int shotDelay) {
this.x = x;
this.y = y;
this.angle = angle;
this.acceleration = acceleration;
this.velocityDecay = velocityDecay;
this.rotationalSpeed = rotationalSpeed;
xVelocity = 0;
yVelocity = 0;
turningLeft = false;
turningRight = false;
accelerating = false;
active = false;
xPts = new int[4];
yPts = new int[4];
flameXPts = new int[3];
flameYPts = new int[3];
this.shotDelay = shotDelay;
shotDelayLeft = 0;
}
public void draw(Graphics g) {
if(accelerating && active) {
for(int i = 0; i < 3; i++) {
flameXPts[i] = (int)(origFlameXPts[i] * Math.cos(angle) - origFlameYPts[i] * Math.sin(angle) + x + .5);
flameYPts[i] = (int)(origFlameXPts[i] * Math.sin(angle) + origFlameYPts[i] * Math.cos(angle) + y + .5);
}
g.setColor(Color.red);
//color of flame
g.fillPolygon(flameXPts, flameYPts, 3);
}
for(int i = 0; i < 4; i++) {
xPts[i] = (int)(origXPts[i] * Math.cos(angle) - origYPts[i] * Math.sin(angle) + x + .5);
yPts[i] = (int)(origXPts[i] * Math.sin(angle) + origYPts[i] * Math.cos(angle) + y + .5);
}
if(active) {
g.setColor(Color.white);
}
else {
g.setColor(Color.darkGray);
}
g.fillPolygon(xPts, yPts, 4);
}
public void move(int scrnWidth, int scrnHeight) {
if(shotDelayLeft > 0) {
shotDelayLeft--;
}
if(turningLeft) {
angle -= rotationalSpeed;
}
if(turningRight) {
angle += rotationalSpeed;
}
if(angle > (2 * Math.PI)) {
angle -= (2 * Math.PI);
}
else if(angle < 0) {
angle += (2 * Math.PI);
}
if(accelerating) {
xVelocity += acceleration * Math.cos(angle);
yVelocity += acceleration * Math.sin(angle);
}
x += xVelocity;
y += yVelocity;
xVelocity *= velocityDecay;
yVelocity *= velocityDecay;
if(x<0) {
x += scrnWidth;
}
else if(x > scrnWidth) {
x -= scrnWidth;
}
if(y < 0) {
y += scrnHeight;
}
else if(y > scrnHeight) {
y -= scrnHeight;
}
}
public void setAccelerating(boolean accelerating) {
this.accelerating = accelerating;
//start or stop accelerating the ship
}
public void setTurningLeft(boolean turningLeft) {
this.turningLeft = turningLeft;
//start or stop turning the ship
}
public void setTurningRight(boolean turningRight) {
this.turningRight = turningRight;
}
public double getX() {
return x;
//returns the ship’s x location
}
public double getY() {
return y;
//returns the ship's y location
}
public double getRadius() {
return radius;
//returns radius of circle that approximates the ship
}
public void setActive(boolean active) {
this.active = active;
//used when the game is paused or unpaused
}
public boolean isActive() {
return active;
}
public boolean canShoot() {
if(shotDelayLeft > 0) {
return false;
}
else {
return true;
}
}
public Shot shoot() {
shotDelayLeft=shotDelay;
//set delay till next shot can be fired
//a life of 40 makes the shot travel about the width of the
//screen before disappearing
return new Shot(x, y, angle, xVelocity, yVelocity, 40);
}
}
Shot.java
import java.awt.*;
public class Shot {
final double shotSpeed = 12;
double x, y, xVelocity, yVelocity;
int lifeLeft;
public Shot(double x, double y, double angle, double shipXVel, double shipYVel, int lifeLeft) {
this.x = x;
this.y = y;
xVelocity = shotSpeed * Math.cos(angle) + shipXVel;
yVelocity = shotSpeed * Math.sin(angle) + shipYVel;
this.lifeLeft = lifeLeft;
}
public void move(int scrnWidth, int scrnHeight) {
lifeLeft--;
x += xVelocity;
y += yVelocity;
if(x < 0) {
x += scrnWidth;
}
else if(x > scrnWidth) {
x -= scrnWidth;
}
if(y < 0) {
y += scrnHeight;
}
else if(y > scrnHeight) {
y -= scrnHeight;
}
}
public void draw(Graphics g) {
g.setColor(Color.yellow);
g.fillOval((int)(x - .5), (int)(y - .5), 3, 3);
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public int getLifeLeft() {
return lifeLeft;
}
}
thanks for looking.
---------------------Edit 12/9/2012------------------------
Tried debugging with NetBeans IDE 7.2.1. It improperly depicts the turning of ship and gives a completely different error:
Exception in thread "Thread-3" java.lang.NullPointerException
at AsteroidsGame.run(AsteroidsGame.java:122)
at java.lang.Thread.run(Thread.java:722)
It is directing attention to the Shot[] shots array inside the run method.
This could be expected as the array for Asteroid[] and Shot[] are set up the same.

Android 2D animation drawing: bad performance

I have an app that draws a grid of dots (let's say 5x5). The user is asked to draw lines on that grid. If the user's finger touches one of the dots in the grid, this dot is being colored to show that this dot is part of a path drawn. In addition a line will be drawn between each two touched dots.
The issue - I get very bad performance, which causes few things:
The application gets really slow.
Motion events in event.getAction() get bad granularity. I meanenter code here that instead of registering a movement each 10 pixels for example, it registers movements each 100 pixels. This, in turn, will causes the app to NOT redraw some dots the user had touched.
Sometimes the motion coordinates are simple wrong: lets say the user is moving her finger from pixel 100 to pixel 500, the reading might show 100...200...150...140...300...400. For some reason the touch location gets messed up in some cases.
Look at the example on how the app "misses out" on dots the user have touched and doesn't draw the green dots:
I've tried few thing:
Adding Thread.sleep(100); to else if(event.getAction() == MotionEvent.ACTION_MOVE) inside onTouchEvent(MotionEvent event), I read that this might give the CPU time to catch up on all those touch events - didn't change a thing
Adding this.destroyDrawingCache() to the very end of doDraw() (I use it instead of onDraw, as was suggested by one tutorial I used). I thought this will clear all event/drawing caching which seems to be slowing down the system - didn't change a thing.
I am fairly new to Android animation so I am not sure how to proceed:
I understand I should do as little as possible in doDraw() (my onDraw()) and onTouchEvent().
I read some stuff about invalidate() but not sure how and when to use it. If I understand correctly, my View gets drawn anew each time doDraw() is called. My grid, for instance, is static - how can I avoid redrawing it?
++++++++++++++++++++++++ UPDATE 7th Oct +++++++++++++++++++++
I tried using canvas.drawCircle(xPos, yPos, 8, mNodePaint); instead of canvas.drawBitmap(mBitmap, xPos, yPos, null);. I thought that if I DIDN'T use actual bitmaps this might improve performance. As a matter of fact - it didn't! I am a bit confused how such a simple application can pose such a heavy load on the device. I must be doing something really the wrong way.
++++++++++++++++++++++++ UPDATE 12th Oct +++++++++++++++++++++
I took into account what #LadyWoodi suggested - I've eliminated all variable declarations out of the loops - anyway it is a bad practice and I also got rid of all the "System.Out" lines I use so I can log app behavior to better understand why I get such a lame performance. I am sad to say that if there was a change in performance (I didn't actually measure frame rate change) it is negligible.
Any other ideas?
++++++++++++++++++++++++ UPDATE 13th Oct +++++++++++++++++++++
As I have a static grid of dots (see hollow black/white dots in screenShot) that never changes during the game I did the following:
-Draw the grid once.
-Capture the drawing as bitmap using Bitmap.createBitmap().
-Use canvas.drawBitmap() to draw the bitmap of the static dots grid.
-When my thread runs I check to see it the grid of dots is drawn. If it is running I will NOT recreate the static dots grid. I will only render it from my previously rendered bitmap.
Surprisingly this changed nothing with my performance! Redrawing the dots grid each time didn't have a true visual effect on app performance.
I decided to use canvas = mHolder.lockCanvas(new Rect(50, 50, 150, 150)); inside my drawing thread. It was just for testing purposes to see if I limit the area rendered each time, I can get the performance better. This DID NOT help either.
Then I turned to the DDMS tool in Eclipse to try and profile the app. What it came up with, was that canvas.drawPath(path, mPathPaint); (Canvas.native_drawPath) consumed about 88.5% of CPU time!!!
But why??! My path drawing is rather simple, mGraphics contains a collection of Paths and all I do is figure out if each path is inside the boundaries of the game screen and then I draw a path:
//draw path user is creating with her finger on screen
for (Path path : mGraphics)
{
//get path values
mPm = new PathMeasure(path, true);
mPm.getPosTan(0f, mStartCoordinates, null);
//System.out.println("aStartCoordinates X:" + aStartCoordinates[0] + " aStartCoordinates Y:" + aStartCoordinates[1]);
mPm.getPosTan(mPm.getLength(), mEndCoordinates, null);
//System.out.println("aEndCoordinates X:" + aEndCoordinates[0] + " aEndCoordinates Y:" + aEndCoordinates[1]);
//coordinates are within game board boundaries
if((mStartCoordinates[0] >= 1 && mStartCoordinates[1] >= 1) && (mEndCoordinates[0] >= 1 && mEndCoordinates[1] >= 1))
{
canvas.drawPath(path, mPathPaint);
}
}
Can anyone see any ill programmed lines of code in my examples?
++++++++++++++++++++++++ UPDATE 14th Oct +++++++++++++++++++++
I've made changes to my doDraw()method. Basically what I do is draw the screen ONLY if something was changed. In all other cases I simply store a cached bitmap of the screen and render it. Please take a look:
public void doDraw(Canvas canvas)
{
synchronized (mViewThread.getSurefaceHolder())
{
if(mGraphics.size() > mPathsCount)
{
mPathsCount = mGraphics.size();
//draw path user is creating with her finger on screen
for (Path path : mGraphics)
{
//get path values
mPm = new PathMeasure(path, true);
mPm.getPosTan(0f, mStartCoordinates, null);
//System.out.println("aStartCoordinates X:" + aStartCoordinates[0] + " aStartCoordinates Y:" + aStartCoordinates[1]);
mPm.getPosTan(mPm.getLength(), mEndCoordinates, null);
//System.out.println("aEndCoordinates X:" + aEndCoordinates[0] + " aEndCoordinates Y:" + aEndCoordinates[1]);
//coordinates are within game board boundaries
if((mStartCoordinates[0] >= 1 && mStartCoordinates[1] >= 1) && (mEndCoordinates[0] >= 1 && mEndCoordinates[1] >= 1))
{
canvas.drawPath(path, mPathPaint);
}
}
//nodes that the path goes through, are repainted green
//these nodes are building the drawn pattern
for (ArrayList<PathPoint> nodePattern : mNodesHitPatterns)
{
for (PathPoint nodeHit : nodePattern)
{
canvas.drawBitmap(mDotOK, nodeHit.x - ((mDotOK.getWidth()/2) - (mNodeBitmap.getWidth()/2)), nodeHit.y - ((mDotOK.getHeight()/2) - (mNodeBitmap.getHeight()/2)), null);
}
}
mGameField = Bitmap.createBitmap(mGridNodesCount * mNodeGap, mGridNodesCount * mNodeGap, Bitmap.Config.ARGB_8888);
}
else
{
canvas.drawBitmap(mGameField, 0f, 0f, null);
}
Now for the results - as long as the device doesn't have to render no paths and simply draws from a bitmap, stuff goes very fast. But the moment I have to rerender the screen using canvas.drawPath() performance becomes as sluggish as a turtle on morphine... The more paths I have (up to 6 and more, which is NOTHING!) the slower the rendering. How odd is this?? - My paths are even not really curvy - the are all straight lines with an occasional turn. What I mean is that the line is not very "complex".
I've add more code below - if you have any improvements ideas.
Many thanks in advance,
D.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Class "Panel" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
Bitmap mNodeBitmap;
int mNodeBitmapWidthCenter;
int mNodeBitmapHeightCenter;
Bitmap mDotOK;
ViewThread mViewThread;
ArrayList<PathPoint> mPathPoints;
private ArrayList<Path> mGraphics = new ArrayList<Path>(3);
private ArrayList<ArrayList<PathPoint>> mNodesHitPatterns = new ArrayList<ArrayList<PathPoint>>();
private Paint mPathPaint;
Path mPath = new Path();
//private ArrayList<Point> mNodeCoordinates = new ArrayList<Point>();
private int mGridNodesCount = 5;
private int mNodeGap = 100;
PathPoint mNodeCoordinates[][] = new PathPoint[mGridNodesCount][mGridNodesCount];
PathMeasure mPm;
float mStartCoordinates[] = {0f, 0f};
float mEndCoordinates[] = {0f, 0f};
PathPoint mPathPoint;
Boolean mNodesGridDrawn = false;
Bitmap mGameField = null;
public Boolean getNodesGridDrawn() {
return mNodesGridDrawn;
}
public Panel(Context context) {
super(context);
mNodeBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dot);
mNodeBitmapWidthCenter = mNodeBitmap.getWidth()/2;
mNodeBitmapHeightCenter = mNodeBitmap.getHeight()/2;
mDotOK = BitmapFactory.decodeResource(getResources(), R.drawable.dot_ok);
getHolder().addCallback(this);
mViewThread = new ViewThread(this);
mPathPaint = new Paint();
mPathPaint.setAntiAlias(true);
mPathPaint.setDither(true); //for better color
mPathPaint.setColor(0xFFFFFF00);
mPathPaint.setStyle(Paint.Style.STROKE);
mPathPaint.setStrokeJoin(Paint.Join.ROUND);
mPathPaint.setStrokeCap(Paint.Cap.ROUND);
mPathPaint.setStrokeWidth(5);
}
public ArrayList<ArrayList<PathPoint>> getNodesHitPatterns()
{
return this.mNodesHitPatterns;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
public void surfaceCreated(SurfaceHolder holder) {
//setPadding(100, 100, 0, 0);
if (!mViewThread.isAlive()) {
mViewThread = new ViewThread(this);
mViewThread.setRunning(true);
mViewThread.start();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (mViewThread.isAlive()) {
mViewThread.setRunning(false);
}
}
//draw the basic nodes grid that the user will use to draw the lines on
//store as bitmap
public void drawNodesGrid(Canvas canvas)
{
canvas.drawColor(Color.WHITE);
for (int i = 0; i < mGridNodesCount; i++)
{
for (int j = 0; j < mGridNodesCount; j++)
{
int xPos = j * mNodeGap;
int yPos = i * mNodeGap;
try
{
//TODO - changed
mNodeCoordinates[i][j] = new PathPoint(xPos, yPos, null);
}
catch (Exception e)
{
e.printStackTrace();
}
canvas.drawBitmap(mNodeBitmap, xPos, yPos, null);
}
}
mNodesGridDrawn = true;
mGameField = Bitmap.createBitmap(mGridNodesCount * mNodeGap, mGridNodesCount * mNodeGap, Bitmap.Config.ARGB_8888);
}
public void doDraw(Canvas canvas)
{
canvas.drawBitmap(mGameField, 0f, 0f, null);
synchronized (mViewThread.getSurefaceHolder())
{
//draw path user is creating with her finger on screen
for (Path path : mGraphics)
{
//get path values
mPm = new PathMeasure(path, true);
mPm.getPosTan(0f, mStartCoordinates, null);
//System.out.println("aStartCoordinates X:" + aStartCoordinates[0] + " aStartCoordinates Y:" + aStartCoordinates[1]);
mPm.getPosTan(mPm.getLength(), mEndCoordinates, null);
//System.out.println("aEndCoordinates X:" + aEndCoordinates[0] + " aEndCoordinates Y:" + aEndCoordinates[1]);
//coordinates are within game board boundaries
if((mStartCoordinates[0] >= 1 && mStartCoordinates[1] >= 1) && (mEndCoordinates[0] >= 1 && mEndCoordinates[1] >= 1))
{
canvas.drawPath(path, mPathPaint);
}
}
//nodes that the path goes through, are repainted green
//these nodes are building the drawn pattern
for (ArrayList<PathPoint> nodePattern : mNodesHitPatterns)
{
for (PathPoint nodeHit : nodePattern)
{
canvas.drawBitmap(mDotOK, nodeHit.x - ((mDotOK.getWidth()/2) - (mNodeBitmap.getWidth()/2)), nodeHit.y - ((mDotOK.getHeight()/2) - (mNodeBitmap.getHeight()/2)), null);
}
}
this.destroyDrawingCache();
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (mViewThread.getSurefaceHolder()) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
//System.out.println("Action downE x: " + event.getX() + " y: " + event.getY());
for (int i = 0; i < mGridNodesCount; i++)
{
for (int j = 0; j < mGridNodesCount; j++)
{
//TODO - changed
//PathPoint pathPoint = mNodeCoordinates[i][j];
mPathPoint = mNodeCoordinates[i][j];
if((Math.abs((int)event.getX() - mPathPoint.x) <= 35) && (Math.abs((int)event.getY() - mPathPoint.y) <= 35))
{
//mPath.moveTo(pathPoint.x + mBitmap.getWidth() / 2, pathPoint.y + mBitmap.getHeight() / 2);
//System.out.println("Action down x: " + pathPoint.x + " y: " + pathPoint.y);
ArrayList<PathPoint> newNodesPattern = new ArrayList<PathPoint>();
mNodesHitPatterns.add(newNodesPattern);
//mNodesHitPatterns.add(nh);
//pathPoint.setAction("down");
break;
}
}
}
}
else if(event.getAction() == MotionEvent.ACTION_MOVE)
{
final int historySize = event.getHistorySize();
//System.out.println("historySize: " + historySize);
//System.out.println("Action moveE x: " + event.getX() + " y: " + event.getY());
coordinateFound:
for (int i = 0; i < mGridNodesCount; i++)
{
for (int j = 0; j < mGridNodesCount; j++)
{
//TODO - changed
//PathPoint pathPoint = mNodeCoordinates[i][j];
mPathPoint = mNodeCoordinates[i][j];
if((Math.abs((int)event.getX() - mPathPoint.x) <= 35) && (Math.abs((int)event.getY() - mPathPoint.y) <= 35))
{
int lastPatternIndex = mNodesHitPatterns.size()-1;
ArrayList<PathPoint> lastPattern = mNodesHitPatterns.get(lastPatternIndex);
int lastPatternLastNode = lastPattern.size()-1;
if(lastPatternLastNode != -1)
{
if(!mPathPoint.equals(lastPattern.get(lastPatternLastNode).x, lastPattern.get(lastPatternLastNode).y))
{
lastPattern.add(mPathPoint);
//System.out.println("Action moveC [add point] x: " + pathPoint.x + " y: " + pathPoint.y);
}
}
else
{
lastPattern.add(mPathPoint);
//System.out.println("Action moveC [add point] x: " + pathPoint.x + " y: " + pathPoint.y);
}
break coordinateFound;
}
else //no current match => try historical
{
if(historySize > 0)
{
for (int k = 0; k < historySize; k++)
{
//System.out.println("Action moveH x: " + event.getHistoricalX(k) + " y: " + event.getHistoricalY(k));
if((Math.abs((int)event.getHistoricalX(k) - mPathPoint.x) <= 35) && (Math.abs((int)event.getHistoricalY(k) - mPathPoint.y) <= 35))
{
int lastPatternIndex = mNodesHitPatterns.size()-1;
ArrayList<PathPoint> lastPattern = mNodesHitPatterns.get(lastPatternIndex);
int lastPatternLastNode = lastPattern.size()-1;
if(lastPatternLastNode != -1)
{
if(!mPathPoint.equals(lastPattern.get(lastPatternLastNode).x, lastPattern.get(lastPatternLastNode).y))
{
lastPattern.add(mPathPoint);
//System.out.println("Action moveH [add point] x: " + pathPoint.x + " y: " + pathPoint.y);
}
}
else
{
lastPattern.add(mPathPoint);
//System.out.println("Action moveH [add point] x: " + pathPoint.x + " y: " + pathPoint.y);
}
break coordinateFound;
}
}
}
}
}
}
}
else if(event.getAction() == MotionEvent.ACTION_UP)
{
// for (int i = 0; i < mGridSize; i++) {
//
// for (int j = 0; j < mGridSize; j++) {
//
// PathPoint pathPoint = mNodeCoordinates[i][j];
//
// if((Math.abs((int)event.getX() - pathPoint.x) <= 35) && (Math.abs((int)event.getY() - pathPoint.y) <= 35))
// {
// //the location of the node
// //mPath.lineTo(pathPoint.x + mBitmap.getWidth() / 2, pathPoint.y + mBitmap.getHeight() / 2);
//
// //System.out.println("Action up x: " + pathPoint.x + " y: " + pathPoint.y);
//
// //mGraphics.add(mPath);
// // mNodesHit.add(pathPoint);
// // pathPoint.setAction("up");
// break;
// }
// }
// }
}
//System.out.println(mNodesHitPatterns.toString());
//create mPath
for (ArrayList<PathPoint> nodePattern : mNodesHitPatterns)
{
for (int i = 0; i < nodePattern.size(); i++)
{
if(i == 0) //first node in pattern
{
mPath.moveTo(nodePattern.get(i).x + mNodeBitmapWidthCenter, nodePattern.get(i).y + mNodeBitmapHeightCenter);
}
else
{
mPath.lineTo(nodePattern.get(i).x + mNodeBitmapWidthCenter, nodePattern.get(i).y + mNodeBitmapWidthCenter);
}
//mGraphics.add(mPath);
}
}
mGraphics.add(mPath);
return true;
}
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Class "ViewThread" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public class ViewThread extends Thread {
private Panel mPanel;
private SurfaceHolder mHolder;
private boolean mRun = false;
public ViewThread(Panel panel) {
mPanel = panel;
mHolder = mPanel.getHolder();
}
public void setRunning(boolean run) {
mRun = run;
}
public SurfaceHolder getSurefaceHolder()
{
return mHolder;
}
#Override
public void run()
{
Canvas canvas = null;
while (mRun)
{
canvas = mHolder.lockCanvas();
//canvas = mHolder.lockCanvas(new Rect(50, 50, 150, 150));
if (canvas != null)
{
if(!mPanel.getNodesGridDrawn())
{
mPanel.drawNodesGrid(canvas);
}
mPanel.doDraw(canvas);
mHolder.unlockCanvasAndPost(canvas);
}
}
}
}
It's just the idea, but I would try to take all the declarations out of the loops. I know that it can be useful to have them localized, however it's usually really time consuming so it could help a little. My second idea was already tested by you in your update so now I am also curious how it will go ;)
You are using a SurfaceView? First of all, I recommend you to use a graphic library for your game... AndEngine for example is pretty easy to use and you will achieve to develop a much more beautiful game than using the Java canvas. The performance is better too.
I can´t find anything wrong with your code, but there is a lot of processing in the draw method, and more important, in the onTouch event. You should avoid to use divisions or heavy math operations in the loops and try to pre-calculate everything before.
But I insist; for something like what you are doing, take a look at this and you will have it up and running in no time!

get an specific object from my arrayList(Java)

hi my problem is that in my code i am calling a method that calculates the different between 2 point and then if that distance is less that 7 it will call another class method that should change the color of the target to red... my problem is that in my arraylist i have 3 or five or depends on the user input targets... so how can i specify the object in my arraylist that is going to be change of color>??? this is my code
package project1;
import java.util.*;
import javax.swing.*;
/**
*
* #author Elvis De Abreu
*/
public class TargetGallery
{
/**ArrayList of Targets initialize as a private*/
private ArrayList<Target> mytargets = new ArrayList<>();
/**Static object for the Target class*/
static Target tg = new Target();
/**Static object for the RifleSite class*/
static RifleSite rs = new RifleSite();
/**Static object for the TargetGallery class*/
static TargetGallery tgy = new TargetGallery();
/**the number of targets input by the user as private*/
private int number = 0;
/**array that store the distance between 2 point for each target*/
private double[] total;
/**
* Method that build the background of the canvas
* with a picture as a environment
*/
private void buildWorld()
{
StdDraw.setXscale(0, 250);
StdDraw.setYscale(0, 250);
StdDraw.picture(75, 130, "bath.jpeg", 450, 285);
}
/**
* Method that draw a weapon in the middle of the
* canvas as a shooter weapon
*/
private void drawShooter()
{
StdDraw.setXscale(0, 250);
StdDraw.setYscale(0, 250);
StdDraw.picture(125, 0, "weapon.png", 80, 45);
}
/**
* randomly generates X locations for the targets
* add them into the array list
*/
private void createTargets()
{
double x = 125;
double y = 175;
double radius = 7;
String input = JOptionPane.showInputDialog("Type a number" +
"between 2 and 5");
number = Integer.parseInt(input);
for(int i = 0; i < number; i++)
{
Target targ = new Target(x, y, radius);
mytargets.add(targ);
Random rand = new Random();
x = rand.nextInt(400) + 10;
for (Target e: mytargets)
{
if ((e.getX() <= (x+10)) || (e.getX() >= (x-10)))
{
mytargets.clear();
i--;
continue;
}
}
}
}
/**
* Method that run different methods which start the program
*/
public void run()
{
tgy.buildWorld(); //call the buildWorld method
tgy.drawShooter(); //call the drawShooter method
tgy.createTargets(); //call the createTarget method
tgy.simulate(); //call the simulate method
}
/**
* calculates the distance between the RifleSite and the Targets
*/
public void calcDistance()
{
//variable declaration/initialization
double distance;
double distance1;
int i = 0;
total = new double[number];
//for each loop to calculate x and y location of RifleSite and Targets
for (Target e: mytargets)
{
distance = Math.pow(e.getX()-rs.getX(), 2.0);
distance1 = Math.pow(e.getY()-rs.getY(), 2.0);
total[i++] = Math.sqrt(distance + distance1);
}
}
/**
* Method that simulates the game
*/
public void simulate()
{
//Variable declaration/initialization
boolean alive = true;
for(Target e: mytargets)
{
e.drawAlive();
}
rs.drawRifleSite();
//loop that will run while there is still targets alive or user press q
while(alive == true)
{
//if user press a key this
if (StdDraw.hasNextKeyTyped())
{
char ch = StdDraw.nextKeyTyped(); //store the key pressed
//if person press Q will quit the program
if (ch == 'q')
{
int done = JOptionPane.showConfirmDialog(null,
"The Program will close now bye :)");
System.exit(0);
}
else if (ch == 'f')
{
tgy.calcDistance(); //calculates the distance
//if statement to check if the distance if less than radius
for(int i = 0; i < number; i++)
{
if (total[i] <= 7)
{
//THIS IS WHERE MY METHOD SHOULD GO
//SHOULD BE SOMETHING LIKE E.drawDead
}
}
}
}
}
}
/**
* Method for the main of the Program
* #param args the command line arguments
*/
public static void main(String[] args)
{
}
}
Like this:mytargets.get(INDEX GO HERE)
i Hope that helps
(the index starts from 0)
For example:
Target t=mytargets.get(0);
if ((t.getX() > 10) && (t.getY() > 10))
{
//blablabla
}