I am trying to move two markers at the same time with ObjectAnimator and AnimatorSet but I don't get it to work, here I share the code I am using.
handler =new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (list.size() > 1 ){
if (index < list.size() - 1) {
index++;
next = index + 1;
}
if (index < list.size() - 1) {
starposition = list.get(index);
endposition = list.get(next);
}
if (index2 < list2.size() - 1) {
index2++;
next2 = index2 + 1;
}
if (index2 < list2.size() - 1) {
starposition2 = list2.get(index2);
endposition2 = list2.get(next2);
}
final ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(marker,"rotation",0,1);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.setDuration(2000);
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
v = objectAnimator.getAnimatedFraction();
logg = v * endposition.longitude + (1 - v)
* starposition.longitude;
latt = v * endposition.latitude + (1 - v)
* starposition.latitude;
LatLng newpos = new LatLng(latt, logg);
marker.setPosition(newpos);
marker.setAnchor(0.5f, 0.5f);
marker.setRotation(getBearing(starposition, newpos));
}
});
final ObjectAnimator objectAnimator2= ObjectAnimator.ofFloat(marker,"rotation",0,1);
objectAnimator2.setInterpolator(new LinearInterpolator());
objectAnimator2.setDuration(2000);
objectAnimator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
h = objectAnimator2.getAnimatedFraction();
logg2 = h * endposition2.longitude + (1 - h)
* starposition2.longitude;
latt2 = h * endposition2.latitude + (1 - h)
* starposition2.latitude;
LatLng newpos2 = new LatLng(latt2,logg2);
marker2.setPosition(newpos2);
marker2.setAnchor(0.5f, 0.5f);
marker2.setRotation(getBearing(starposition2, newpos2));
}
});
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(objectAnimator,objectAnimator2);
animatorSet.start();
handler.postDelayed(this, 3000);
}
}
},3000);
I have two lists where I store the LatLngs for each marker, then I create the Objectanimator to give the animation to each marker, but ... when I run it, the two do not move at the same time but in a sequential when the first one ends, the other begins to move
Related
I already tried to clamp it with mathf or hardocding it, but it didnt help either, it just slips trough, every time I rotate the camera on the edge of the map (min/max hsp - min/max vsp) the given edges of the terrain.
I'm out of ideas and searched days for a similar problem in hope to see my mistake and now I'm here. Hopefully someone can help me and show me the mistake I made. I want to learn so badly. you can see the code I used here:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMovementScript : MonoBehaviour
{
float speed = 1f;
float zoomSpeed = 10f;
float rotateSpeed = 50f;
float maxHeight = 200f;
float minHeight = 20f;
float minHsp = 10f;
float maxHsp = 750f;
float minVsp = 10f;
float maxVsp = 750f;
Vector2 p1;
Vector2 p2;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.LeftShift))
{
speed = 1f;
zoomSpeed = 2000f;
}
else
{
speed = 0.5f;
zoomSpeed = 1550f;
}
float hsp = transform.position.y * speed * Input.GetAxis("Horizontal") * Time.deltaTime;
float vsp = transform.position.y * speed * Input.GetAxis("Vertical") * Time.deltaTime;
float scrollSP = Mathf.Log(transform.position.y) * -zoomSpeed * Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime;
if ((transform.position.y >= maxHeight) && (scrollSP > 0))
{
scrollSP = 0;
}
else if ((transform.position.y <= minHeight) && (scrollSP <0))
{
scrollSP = 0;
}
if((transform.position.y + scrollSP) > maxHeight)
{
scrollSP = maxHeight - transform.position.y;
}
else if((transform.position.y + scrollSP) < minHeight)
{
scrollSP = minHeight - transform.position.y;
}
if ((transform.position.x >= maxHsp) && (hsp > 0))
{
hsp = 0;
}
else if ((transform.position.x <= minHsp) && (hsp < 0))
{
hsp = 0;
}
if ((transform.position.x + hsp) > maxHsp)
{
hsp = maxHsp - transform.position.x;
}
else if ((transform.position.x + hsp) < minHsp)
{
hsp = minHsp - transform.position.x;
}
if ((transform.position.z >= maxVsp) && (vsp > 0))
{
vsp = 0;
}
else if ((transform.position.z <= minVsp) && (vsp < 0))
{
vsp = 0;
}
if ((transform.position.z + vsp) > maxVsp)
{
vsp = maxVsp - transform.position.z;
}
else if ((transform.position.z + vsp) < minVsp)
{
vsp = minVsp - transform.position.z;
}
Vector3 verticalMove = new Vector3(0,scrollSP,0);
Vector3 lateralMove = hsp * transform.right;
Vector3 forwardMove = transform.forward;
forwardMove.y = 0;
forwardMove.Normalize();
forwardMove *= vsp;
Vector3 move = verticalMove + lateralMove + forwardMove;
transform.position += move;
getCameraRotation();
}
void getCameraRotation()
{
if(Input.GetMouseButtonDown(2))
{
p1 = Input.mousePosition;
}
if(Input.GetMouseButton(2))
{
p2 = Input.mousePosition;
float dx = (p2 - p1).x * rotateSpeed * Time.deltaTime;
float dy = (p2 - p1).y * rotateSpeed * Time.deltaTime;
transform.rotation *= Quaternion.Euler(new Vector3(0,dx,0));
transform.GetChild(0).transform.rotation *= Quaternion.Euler(new Vector3(-dy,0,0));
p1 = p2;
}
}
}
Item class:
public class Item {
public float x, y, speedx, speedy;
public Rectangle container;
public Texture texture;
static Timer timer = new Timer();
static int amount;
static int spawned;
public int itemtype;
// float delay = 1; // seconds
public void move() {
x += speedx;
y += speedy;
container.x = x;
container.y = y;
}
public void setTexture(int itemtype){
switch(itemtype){
case 1:
texture = new Texture("items/item1.png");
break;
case 2:
texture = new Texture("items/item2.png");
break;
case 3:
texture = new Texture("items/item3.png");
break;
case 4:
texture = new Texture("items/item4.png");
break;
case 5:
texture = new Texture("items/item5.png");
break;
case 6:
texture = new Texture("items/item6.png");
break;
case 7:
texture = new Texture("items/item7.png");
break;
case 8:
texture = new Texture("items/item8.png");
break;
case 9:
texture = new Texture("items/item9.png");
break;
case 10:
texture = new Texture("items/item10.png");
break;
default:
texture = new Texture("items/error.png");
break;
}
}
public static void spawnItem(int amount){
Item.amount = amount;
mainscreen.items.clear();
// for(int spawned = 0; spawned <= amount; spawned++){
timer.schedule(new Timer.Task() {
#Override
public void run() {
if (mainscreen.canclick == false) {
Item item = new Item();
item.x = 600;
item.y = -42;
item.speedx = -20;
item.speedy = 0;
Rectangle itemcontainer = new Rectangle();
itemcontainer.x = item.x;
itemcontainer.y = item.y;
itemcontainer.width = mainscreen.container.getWidth() / 4f;
itemcontainer.height = mainscreen.container.getHeight() - 15f;
item.container = itemcontainer;
item.itemtype = MathUtils.random(1, 10);
item.setTexture(item.itemtype);
mainscreen.items.add(item);
spawned++;
}
for (Item item : mainscreen.items) {
if (item.x <= -4000) {
if (spawned >= Item.amount) {
mainscreen.canclick = true;
timer.stop();
spawned = 0;
}
} else {
}
}
}
}, 0, 0.325f);
}
public void dispose(){
texture.dispose();
}
}
Mainscreen class:
public class mainscreen implements Screen, GestureDetector.GestureListener,InputProcessor {
#Override
public void render(float delta) {
this.delta = delta;
Gdx.gl.glClearColor(115 / 255F, 115 / 255F, 115 / 255F, 1 / 255F);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
if(Gdx.input.justTouched()) {
Vector3 touch1 = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touch1);
if (debug.contains(touch1.x, touch1.y)) {
items.clear();
}
if (start.contains(touch1.x, touch1.y)) {
if (canclick == true) {
canclick = false;
Item.spawnItem(20);
}
}
}
}
LOG:
On first click start:
(After the Timer has finished)
canclick: true
items list: [com.abc.luckyllama.Item#37237aa0, com.abc.luckyllama.Item#2de938e3, com.abc.luckyllama.Item#3cb912d5, com.abc.luckyllama.Item#2bae592c, com.abc.luckyllama.Item#774c083, com.abc.luckyllama.Item#633edeae, com.abc.luckyllama.Item#176557a6, com.abc.luckyllama.Item#4edb1b5f, com.abc.luckyllama.Item#6f8abadf, com.abc.luckyllama.Item#7a54d22e, com.abc.luckyllama.Item#473162a5, com.abc.luckyllama.Item#51a698ff, com.abc.luckyllama.Item#6bc08c56, com.abc.luckyllama.Item#37d9e6a2, com.abc.luckyllama.Item#7bb19eb6, com.abc.luckyllama.Item#1eb5805f, com.abc.luckyllama.Item#71780de3, com.abc.luckyllama.Item#9ec0998, com.abc.luckyllama.Item#7edf723d, com.abc.luckyllama.Item#4c5aa2c1]
After clicking the debug button(clears arraylist):
canclick: true
items list: []
After clicking the start button again:
(After the Timer has finished)
canclick: true
items list: [com.abc.luckyllama.Item#7d7cb9bc, com.abc.luckyllama.Item#1435cf42, com.abc.luckyllama.Item#117e1963, com.abc.luckyllama.Item#82bfd27, com.abc.luckyllama.Item#108214c7, com.abc.luckyllama.Item#2a77864a, com.abc.luckyllama.Item#4b232766, com.abc.luckyllama.Item#1cb629e0, com.abc.luckyllama.Item#1c92229d, com.abc.luckyllama.Item#ac1b293, com.abc.luckyllama.Item#588bbcba, com.abc.luckyllama.Item#75df6762, com.abc.luckyllama.Item#78d4358e, com.abc.luckyllama.Item#7f86452d, com.abc.luckyllama.Item#7aed480b, com.abc.luckyllama.Item#7407d443, com.abc.luckyllama.Item#2da6e708, com.abc.luckyllama.Item#604470bc, com.abc.luckyllama.Item#70f9d1af, com.abc.luckyllama.Item#3a16a63f, com.abc.luckyllama.Item#201288d2, com.abc.luckyllama.Item#6310ddfc, com.abc.luckyllama.Item#5d5a1c98, com.abc.luckyllama.Item#52727e52, com.abc.luckyllama.Item#669228d6]
You see that the Items inside the ArrayList didn't get cleared. It increased. I think that's because the instances of Item created in spawnItem() are still there. How do I fix this?
I noticed that every time I click the button there aren't more items. The items are spawned faster. But how to stop this?
I fixed it! The problem was that I needed to create a Timer.Task seperately and the use task.cancel(); to stop the Timer.Task:
import com.badlogic.gdx.utils.Timer;
public class Item {
public static Timer.Task task;
public static void spawnItem(int amount){
Item.amount = amount;
task = new Timer.Task() {
#Override
public void run() {
if (mainscreen.canclick == false) {
item = new Item();
item.x = 600;
item.y = -42;
item.speedx = -20;
item.speedy = 0;
Rectangle itemcontainer = new Rectangle();
itemcontainer.x = item.x;
itemcontainer.y = item.y;
itemcontainer.width = mainscreen.container.getWidth() / 3f;
itemcontainer.height = mainscreen.container.getHeight() - 15f;
item.container = itemcontainer;
item.itemtype = MathUtils.random(1, 10);
item.setTexture(item.itemtype);
mainscreen.items.add(item);
mainscreen.itemsspawned += 1;
// mainscreen.items.remove(item);
spawned++;
}
for (Item item : mainscreen.items) {
if (item.x <= -4000) {
if (spawned >= Item.amount) {
mainscreen.canclick = true;
timer.clear();
timer.stop();
task.cancel();
spawned = 0;
}
}
}
}
};
timer.schedule(task, 0, 0.4f);
}
}
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 ;)
I keep getting
Error #2006: The supplied index is out of bounds.
at flash.display::DisplayObjectContainer/getChildAt()
at Main/onFrame()
This is mostly referring to this part of my code
else if (comp) //if completion is true
{
var animation = char.getChildAt(2); //
if (animation.currentFrame == animation.totalFrames)
{
animation.stop();
addChild(end);
My animation that I am pulling at the second frame also isn't running at all, though I have checked the symbol and the frames within it, and it should work fine. I'm pretty new to code and this is what I have been taught so far.
This is the rest of my code here.
We are supposed to make a basic game where our character walks to a power up and does a power up animation, followed by an end game title.
package
{
import flash.display.MovieClip;
import fl.motion.easing.Back;
import flash.sampler.Sample;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Main extends MovieClip
{
var bg:Background;
var b:Bubbles;
var b2:Bubbles;
var s:Seaweed;
var pressingRight:Boolean = false;
var pressingLeft:Boolean = false;
var comp:Boolean = false;
var speed:int = 10;
var char:Character;
var pu:PowerUp;
var hit:hit1
var end:EndGame;
public function Main()
{
bg = new Background;
addChild(bg);
char = new Character();
addChild(char);
char.x = stage.stageWidth/2;
char.y = 488;
b = new Bubbles();
addChild(b);
b2 = new Bubbles();
addChild(b2);
b2.y = +b2.height;
s = new Seaweed();
addChild(s);
pu = new PowerUp();
addChild(pu);
pu.x = 200;
pu.y = 450;
pu.height = 50;
pu.scaleX = pu.scaleY;
pu.gotoAndStop("SPIN");
hit = new hit1;
addChild(hit);
hit.x = char.x
hit.y = char.y - 50
end = new EndGame();
end.x = stage.stageWidth/2;
end.y = stage.stageHeight/2;
stage.addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
}//main()
public function onFrame(e:Event)
{
if (!comp)
//Bubble Movement
b.y -= 1;
b2.y -= 1;
if (b.y >= stage.stageHeight)
{
b.y = b2.y + bg.height;
}
else if (b2.y >= stage.stageHeight)
{
b2.y = b.y + b2.height;
}
//Background & Character Movement
if (pressingRight && char.x < stage.stageWidth/2)
{
char.x += speed * 0.4
}
else if (pressingRight == true && (bg.width + bg.x) > stage.stageWidth)
{
bg.x -= speed * 0.4;
s.x -= speed * 0.6;
pu.x -= speed * 0.4;
}
else if (pressingRight == true)
{
char.x += speed * 0.4;
}
if (pressingLeft == true && char.x > stage.stageWidth/2)
{
char.x -= speed * 0.4;
}
else if (pressingLeft == true && bg.x <0)
{
bg.x += speed * 0.4;
s.x += speed * 0.6;
pu.x += speed * 0.4;
}
else if (pressingLeft)
{
char.x -= speed * 0.4;
}
//Boundaries
if (char.x > stage.stageWidth)
{
char.x = stage.stageWidth;
}
else if (char.x < 0)
{
char.x = 0;
}
//Character Looking Directions
if (pressingLeft == true)
{
char.scaleX = -1;
hit.x = char.x
}
if (pressingRight == true)
{
char.scaleX = 1;
hit.x = char.x
}
//Character Movements
if (pressingRight || pressingLeft)
{
char.gotoAndStop("WALK");
}
else if (!pressingRight || !pressingLeft)
{
char.gotoAndStop("IDLE");
}
//Getting the Power up
if (pu.hitTestObject(hit))
{
char.gotoAndStop("POWER");
comp = true;
pu.gotoAndStop("GONE");
}
// !end
else if (comp) //if completion is true
{
var animation = char.getChildAt(2); //
if (animation.currentFrame == animation.totalFrames)
{
animation.stop();
addChild(end);
}
}//Comp
}//onFrame
public function keyPressed(k:KeyboardEvent)
{
if (k.keyCode == Keyboard.RIGHT)
{
pressingRight = true;
}
else if (k.keyCode == Keyboard.LEFT)
{
pressingLeft = true;
}
} // keyPressed()
public function keyReleased(k:KeyboardEvent)
{
if (k.keyCode == Keyboard.RIGHT)
{
pressingRight = false;
}
else if (k.keyCode == Keyboard.LEFT)
{
pressingLeft = false;
}
} // keyReleased()
}//public class()
}//package()
If you're using a language with zero-based indexing (where array indexes start at 0, not 1) Then this could be the problem.
Frame 1 would be at index [0] and frame 2 would be at index [1].
If you have 2 frames for example and try to access the frame at index[2] you are stepping beyond the bounds of your array and this is probably why you are getting that error message.
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.