Live Wallpaper with bouncing effect - java

I'm creating a life wallpaper for android which "ic_launcher" is able to bounce when it "hit" the left/right edge of the screen.
public class LiveWallpaperService extends WallpaperService
{
int x,y;
public void onCreate()
{
super.onCreate();
}
public void onDestroy()
{
super.onDestroy();
}
public Engine onCreateEngine()
{
return new MyWallpaperEngine();
}
class MyWallpaperEngine extends Engine
{
private final Handler handler = new Handler();
private final Runnable drawRunner = new Runnable() {
#Override
public void run() {
draw();
}
};
private boolean visible = true;
public Bitmap image1,backgroundImage;
MyWallpaperEngine()
{
image1 = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
backgroundImage = BitmapFactory.decodeResource(getResources(),R.drawable.pika);
x=130;
y=200;
}
public void onCreate(SurfaceHolder surfaceHolder)
{
super.onCreate(surfaceHolder);
}
#Override
public void onVisibilityChanged(boolean visible)
{
this.visible = visible;
if (visible)
{
handler.post(drawRunner);
}
else
{
handler.removeCallbacks(drawRunner);
}
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder)
{
super.onSurfaceDestroyed(holder);
this.visible = false;
handler.removeCallbacks(drawRunner);
}
public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels)
{
draw();
}
void draw()
{
final SurfaceHolder holder = getSurfaceHolder();
int xVelocity = 10;
Canvas c = null;
try
{
c = holder.lockCanvas();
c.drawColor(Color.BLACK);
if (c != null)
{
c.drawBitmap(backgroundImage, 0, 0, null);
c.drawBitmap(image1, x,y, null);
int width=c.getWidth();
x += xVelocity;
if(x>=width)
{xVelocity = -xVelocity;
}
}
}
finally
{
if (c != null)
holder.unlockCanvasAndPost(c);
}
handler.removeCallbacks(drawRunner);
if (visible)
{
handler.postDelayed(drawRunner, 10);
}
}
}
}
The ic_launcher won't bounce back when it met the edge of the screen(it just keep moving to the right until I can't see it any more), can some one help me about it? I guess the problem is in this few lines
int width=c.getWidth();
x += xVelocity;
if(x>=width)
{xVelocity = -xVelocity;
}
}
I'm still a newbie in android programming, Thanks for helping me :)

Following on from your comments: you are resetting velocity each time you call draw();
move
int xVelocity = 10;
so it is at the top with int x,y;
int x,y;
int xVelocity = 10;
int velValue = 10;
int velInvValue = -10;
Then keep some better inverse code like:
if(x >= width)
{
xVelocity = velInvValue;
}
else if(x <= 0)
{
xVelocity = velValue;
}
x += xVelocity;

Related

Setter not changing the value of the variable in my class

I have been working at it for some time and looking it up online however can't find anything.
I'm trying to work out why the Log I created under
Player.Update() is always returning 0 whereas the Log in my Setter is reporting the right values.
The relevant code should be below.
MainActivity
package com.Frenchie.AnimatedSprite;
import ...
public class MainActivity extends Activity implements SensorEventListener {
//Accelerometer
private SensorManager senSensorManager;
private Sensor senAccelerometer;
private static int DIRECTION_STATIONARY = 0;
private static int DIRECTION_DOWN = 1;
private static int DIRECTION_LEFT = 2;
private static int DIRECTION_RIGHT = 3;
private static int DIRECTION_UP = 4;
Player player;
GameView gameView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameView = new GameView(this);
player = new Player();
setContentView(gameView);
//Accelerometer
senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
senSensorManager.registerListener(this, senAccelerometer , SensorManager.SENSOR_DELAY_FASTEST);
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
Sensor mySensor = sensorEvent.sensor;
if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) {
if (sensorEvent.values[0] < -1){
player.setDirection(DIRECTION_UP);
//Log.d("onSensorChanged", ""+ player.getDirection());
}
else if (sensorEvent.values[0] > 1){
player.setDirection(DIRECTION_DOWN);
}
else if (sensorEvent.values[1] < -1){
player.setDirection(DIRECTION_LEFT);
}
else if (sensorEvent.values[1] > 1){
player.setDirection(DIRECTION_RIGHT);
}
else{
player.setDirection(DIRECTION_STATIONARY);
}
//Log.d("Player Update", "X:" +sensorEvent.values[0]+ " Y:" +sensorEvent.values[1]+ " Z:" +sensorEvent.values[2] + " Direction: " + direction);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
}
Player.java
package com.Frenchie.AnimatedSprite;
import ...
public class Player {
private Bitmap sprite;
private int x, y, speed;
//Animation Variables
private static final int SPRITE_ROWS = 4;
private static final int SPRITE_COLUMNS = 4;
private int currentFrame, width, height, srcY, srcX, direction;
Rect src, dst;
//Static Directions
private static int DIRECTION_STATIONARY = 0;
private static int DIRECTION_DOWN = 1;
private static int DIRECTION_LEFT = 2;
private static int DIRECTION_RIGHT = 3;
private static int DIRECTION_UP = 4;
GameView gameView;
public Player (Context context, GameView gameView){
this.gameView = gameView;
x = 100;
y = 500;
speed = 30;
sprite = BitmapFactory.decodeResource(context.getResources(), R.drawable.player);
width = sprite.getWidth() / SPRITE_COLUMNS;
height = sprite.getHeight() / SPRITE_ROWS;
}
public Player() {
}
public void Update() {
Log.d("Player | Update", "" + direction);
if (direction == DIRECTION_UP){
y -= speed;
}
else if (direction == DIRECTION_DOWN){
y += speed;
}
else if (direction == DIRECTION_RIGHT){
x += speed;
}
else if (direction == DIRECTION_LEFT){
x -= speed;
}
else if (direction == 0){
}
}
public void UpdateAnim(){
currentFrame = ++currentFrame % SPRITE_COLUMNS;
srcX = currentFrame * width;
if (direction == DIRECTION_RIGHT){
srcY = 2 * height;
}
else if (direction == DIRECTION_LEFT){
srcY = 1 * height;
}
if (direction == DIRECTION_DOWN){
srcY = 0 * height;
}
else if (direction == DIRECTION_UP){
srcY = 3 * height;
}
src = new Rect(srcX, srcY, srcX + width, srcY + height);
dst = new Rect(x, y, x + width, y + height);
}
public Rect getSrc(){
return src;
}
public Rect getDst(){
return dst;
}
public Bitmap getSprite() {
return sprite;
}
public void setDirection(int mainDirection) {
this.direction = mainDirection;
Log.d("Setter", "" + direction);
}
}
GameView
package com.Frenchie.AnimatedSprite;
import ...
public class GameView extends SurfaceView implements Runnable {
private Canvas canvas;
private SurfaceHolder surfaceHolder;
private Thread thread;
Player player;
public GameView(Context context) {
super(context);
player = new Player(context, this);
surfaceHolder = getHolder();
thread = new Thread(this);
thread.start();
}
#Override
public void run() {
while (true) {
Update();
DrawCanvas();
}
}
private void Update() {
player.Update();
player.UpdateAnim();
Control();
}
private void DrawCanvas() {
canvas = surfaceHolder.lockCanvas();
if (surfaceHolder.getSurface().isValid()) {
canvas.drawColor(Color.MAGENTA);
canvas.drawBitmap(player.getSprite(), player.getSrc(), player.getDst(), null);
surfaceHolder.unlockCanvasAndPost(canvas);
} else {
Log.d("Run", "Surface Invalid");
}
}
private void Control() {
try {
thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
If you need any more information let me know.

App crush while running a simple ball app [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to launch a very basic app - a ball that should bounce on the screen but I am getting an error while trying to launch app on device.
Here's my code, I may have some errors but please explain to me what are they and how could I fix them, I'm new to android development..
public class Ball {
float x;
float y;
boolean movingRight;
boolean movingBottom;
float screenWidth;
float screenHeight;
public Ball(float x, float y, float screenWidth, float screenHeight) {
this.x = x;
this.y = y;
this.screenWidth = screenWidth;
this.screenHeight = screenHeight - 150;
this.movingBottom = false;
this.movingRight = false;
}
public void move() {
if (movingRight)
this.x++;
else
this.x--;
if (movingBottom)
this.y++;
else
this.y--;
if (this.x >= this.screenWidth)
this.movingRight = false;
else if (this.x <= 1)
this.movingRight = true;
if (this.y >= this.screenHeight)
this.movingBottom = false;
else if (this.y <= 1)
this.movingBottom = true;
}
public float getX(){
return this.x;
}
public float getY() {
return this.y;
}
public class MySurfaceView extends SurfaceView{
private Ball ball;
private SurfaceHolder holder;
Paint paint;
public Paint getBallPaint()
{
if(paint == null)
{
paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(3);
}
return this.paint;
}
public MySurfaceView(Context context) {
super(context);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas c = holder.lockCanvas(null);
draw(c);
holder.unlockCanvasAndPost(c);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
}
#Override
public void draw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.drawCircle(ball.x,ball.y,15,getBallPaint());
}
}
public class GameLoopThread extends Thread {
private MySurfaceView view;
private boolean running = false;
public GameLoopThread(MySurfaceView view) {
this.view = view;
}
public void setRunning(boolean run) {
running = run;
}
#Override
public void run() {
while (running) {
Canvas c = null;
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.draw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
}
}
}
public class MainActivity extends ActionBarActivity {
Ball ball;
MySurfaceView mySurfaceView;
GameLoopThread gameLoopThread;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int screenWidth;
screenWidth = getWindowManager().getDefaultDisplay().getWidth();
int screenHeight;
screenHeight = getWindowManager().getDefaultDisplay().getHeight();
ball = new Ball(screenWidth / 2, screenHeight / 2, screenWidth,screenHeight);
gameLoopThread = new GameLoopThread(mySurfaceView);
gameLoopThread.start();
mySurfaceView = new MySurfaceView(this);
setContentView(mySurfaceView);
}
I cannot tell if there are other errors but most obvious one is that you are using mySurfaceView before you have created it.
You should change initialization order to:
mySurfaceView = new MySurfaceView(this);
setContentView(mySurfaceView);
gameLoopThread = new GameLoopThread(mySurfaceView);
gameLoopThread.start();

Java 2D Game adding bombs

I'm very new to game design (this is my first attempt) and this project will be used to create an android game.
I'm trying to make a simple game (as simple as possible).
What I need:
A background
a ship (that can move left an right at the bottom of the screen)
Enemies (Bombs dropping down from the sky)
projectiles (to shoot bombs with, shoot straight up)
Score (in the upper corner)
I have studied this tutorial:
http://www.kilobolt.com/game-development-tutorial.html
and changed code to get this:
http://i297.photobucket.com/albums/mm231/mabee84/Battleship.png
the black rectangles are projectiles.
Now I need to create the bombs but I can't figure out how to implement them.
they need to spawn at fixed y-value and a random x-value (within the screen)
Upon shooting on the bombs they should die but if bombs hit the ship game is over.
Please help i'm a bit stuck.
package kiloboltgame;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
import java.util.ArrayList;
public class StartingClass extends Applet implements Runnable, KeyListener {
private Ship ship;
public static Bomb b1, b2;
public static int score = 0;
private Font font = new Font(null, Font.BOLD, 30);
private Image image, Battleship, Background, Bomb;
private static Background bg1, bg2;
private URL base;
private Graphics second;
#Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("BattleShip");
try{
base = getDocumentBase();
}catch (Exception e){
//TODO: handle exception
}
//Image Setups
Battleship = getImage(base, "data/Battleship.png");
Background = getImage(base, "data/Background.png");
Bomb = getImage(base, "data/Bomb1.png");
}
#Override
public void start() {
bg1 = new Background(0, 0);
bg2 = new Background(800, 0);
ship = new Ship();
b1 = new Bomb(340, 100);
b2 = new Bomb(700, 100);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void run() {
while (true) {
ship.update();
ArrayList projectiles = ship.getProjectiles();
for(int i = 0; i < projectiles.size(); i++){
Projectile p = (Projectile) projectiles.get(i);
if(p.isVisible() == true){
p.update();
}else{
projectiles.remove(i);
}
}
b1.update();
b2.update();
bg1.update();
bg2.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void update(Graphics g) {
if(image == null){
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.drawImage(Background, bg1.getBgX(), bg1.getBgY(), this);
ArrayList projectiles = ship.getProjectiles();
for(int i = 0; i < projectiles.size(); i++){
Projectile p = (Projectile) projectiles.get(i);
g.setColor(Color.BLACK);
g.fillRect(p.getX(), p.getY(), 5, 10);
}
g.drawImage(Battleship, ship.getCenterX() + 230, ship.getCenterY() -23, this);
g.drawImage(Bomb, b1.getCenterX() - 20, b1.getCenterY() - 20, this);
g.drawImage(Bomb, b2.getCenterX() - 20, b2.getCenterY() - 20, this);
g.setFont(font);
g.setColor(Color.BLACK);
g.drawString(Integer.toString(score), 710, 30);
}
#Override
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()){
case KeyEvent.VK_LEFT:
ship.moveLeft();
break;
case KeyEvent.VK_RIGHT:
ship.moveRight();
break;
case KeyEvent.VK_CONTROL:
ship.shoot();
score = score +100;
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
ship.stop();
break;
case KeyEvent.VK_RIGHT:
ship.stop();
break;
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public static Background getBg1() {
return bg1;
}
}
package kiloboltgame;
import java.util.ArrayList;
public class Ship {
//In Java, Class Variables should be private so that only its methods can change them.
private int centerX = 100;
private int centerY = 382;
private int speedX = 0;
private int speedY = 1;
private ArrayList<Projectile> projectiles = new ArrayList<Projectile>();
public void update() {
// Moves Character or Scrolls Background accordingly.
if (speedX < 0) {
centerX += speedX;
} else if (speedX == 0) {
System.out.println("Do not scroll the background.");
} else {
if (centerX <= 440) {
centerX += speedX;
} else {
System.out.println("Scroll Background Here");
}
}
// Updates Y Position
if (centerY + speedY >= 382) {
centerY = 382;
}else{
centerY += speedY;
}
// Prevents going beyond X coordinate of 0
if (centerX + speedX <= -230) {
centerX = -229;
}
}
public void moveRight() {
speedX = 6;
}
public void moveLeft() {
speedX = -6;
}
public void shoot(){
Projectile p = new Projectile(centerX + 285, centerY -10);
projectiles.add(p);
}
public ArrayList getProjectiles(){
return projectiles;
}
public void stop() {
speedX = 0;
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public int getSpeedX() {
return speedX;
}
public int getSpeedY() {
return speedY;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
}
package kiloboltgame;
public class Background {
private int bgX, bgY, speedX;
public Background(int x, int y){
bgX = x;
bgY = y;
speedX = 0;
}
public void update() {
bgX += speedX;
if (bgX <= -800){
bgX += 1600;
}
}
public int getBgX() {
return bgX;
}
public int getBgY() {
return bgY;
}
public int getSpeedX() {
return speedX;
}
public void setBgX(int bgX) {
this.bgX = bgX;
}
public void setBgY(int bgY) {
this.bgY = bgY;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
}
public class Projectile {
private int x, y, speedY;
private boolean visible;
public Projectile(int startX, int startY) {
x = startX;
y = startY;
speedY = -7;
visible = true;
}
public void update() {
y += speedY;
if(y > 480){
visible = false;
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getSpeedY() {
return speedY;
}
public boolean isVisible() {
return visible;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
}
package kiloboltgame;
public class Enemy {
private int maxHealth, currentHealth, power, speedX, centerX, centerY;
private Background bg = StartingClass.getBg1();
//Behavioral Methods
public void update(){
centerX += speedX;
speedX = bg.getSpeedX();
}
public void die(){
}
public void attack(){
}
public int getMaxHealth() {
return maxHealth;
}
public int getCurrentHealth() {
return currentHealth;
}
public int getPower() {
return power;
}
public int getSpeedX() {
return speedX;
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public Background getBg() {
return bg;
}
public void setMaxHealth(int maxHealth) {
this.maxHealth = maxHealth;
}
public void setCurrentHealth(int currentHealth) {
this.currentHealth = currentHealth;
}
public void setPower(int power) {
this.power = power;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setBg(Background bg) {
this.bg = bg;
}
}
package kiloboltgame;
public class Bomb extends Enemy {
public Bomb(int centerX, int centerY) {
setCenterX(centerX);
setCenterY(centerY);
}
}
This is all code that i have so far (I know the background is f*ed since the game this is based on is scrolling right and i haven't fixed it yet.
I recommend putting all object creation in a seperate part of the program. I'd make a BombFactory with a makeBomb mathod that returns a new Bomb instance. Inside the factory, figure out the x-coordinate, for instance using a randomiser. As parameters, you could specify a y-coordinate and possibly an upper and lower bound for the x. This way you can make new Bombs on the fly.
public class BombFactory {
private final Random rand;
public BombFactory() {
this.rand = new Random();
}
public Bomb makeBomb(int lowerboundX, int rangeX, int yPos) {
final int xPos = lowerboundX + rand.nextInt(rangeX);
return new Bomb(xPos, yPos);
}
}
As for the behaviour, I'd look into inheritance and interfaces some more. I see a lot of methods occurring more than once. You generally want to avoid that kind of duplication. You can start by taking all the methods having something to do with coords or movement and putting them in an abstract base class.
You can make a method inside Enemy that checks for a collision and responds to that in different ways, depending on how the subclass overrides it. In case of a Bomb, it would probably always kill itself and whatever it came in contact with.

why wont my program paintComponent() if I set an ImageIcon and Image?

I've tried to find similar questions, but I think I have a unique situation here.
I am programming a game in java, my main class creates a frame which adds a component class which is an extension of JPanel. Basically, I draw these ovals and they move around and do different things, and I want to implement a method inside of one my classes which will use an image instead of an oval. However, anytime I try to create and image from a file, the program will not run the overridden "paintComponent(Graphics g)" method.
My main:
package mikeengine;
import javax.swing.JFrame;
public class MikeEngine {
static final int fx = 1300;
static final int fy = 800;
static final int px = 1292;
static final int py = 767;
static interactivePanel levelPanel;
public static void pause() {
try {
Thread.sleep(10); // wait 10ms
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("MEngine");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(fx, fy);
frame.setResizable(false);
frame.setVisible(true);
levelPanel = new interactivePanel();
addship();
frame.getContentPane().add(levelPanel);
levelPanel.requestFocusInWindow();
while (true) {
pause();
levelPanel.move();
levelPanel.repaint();
}
}
static void addship() {
PlayerShip ship = new PlayerShip(100, 25, 25, px, 0, py, 0);
ship.setGraphic("C:/Users/asdf/Documents/NetBeansProjects/mikeEngine/src/mikeengine/res/right-arrow.jpg");
levelPanel.addObject(ship);
for (int i = 0; i < 5; i++) {
PlayerShip ship2 = new PlayerShip((int) (Math.random() * 1000) + 100, (int) (Math.random() * 1000) + 100, 25, px, px / 2, py, 0);
ship2.setMovement((int) (Math.random() * 10) / 5, (int) (Math.random() * 10) / 2);
levelPanel.addObject(ship2);
}
}
}
now, if I comment out the line:
ship.setGraphic("C:/Users/asdf/Documents/NetBeansProjects/mikeEngine/src/mikeengine/res/right-arrow.jpg");
everything renders perfectly.
I don't even paint the image that is going to be created. The image variable is just part of a class and it is currently just being created and doing nothing, so I don't understand how it affects the paintcomponentMethod(), if the paintComponent() isn't even told to try to paint the image ever.
The "PlayerShip" class extends the abstract "OnScreenObject" class (you really shouldn't need to see the code for PlayerShip, it only overrides one irrelevant method).
OnScreenObject looks like so:
package mikeengine;
import java.awt.Color;
import java.awt.Image;
import javax.swing.ImageIcon;
public abstract class OnScreenObject {
private ImageIcon graphic;
Image g;
protected int xmin;
protected int ymin;
protected int xsize;
protected int ysize;
protected int rise;
protected int run;
protected int containerYMax;
protected int containerYMin;
protected int containerXMax;
protected int containerXMin;
protected boolean visible;
protected boolean allowedOffscreen;
protected boolean isSelected;
protected Color color;
OnScreenObject(int x, int y, int sizeX, int sizeY, int cxMax, int cxMin, int cyMax, int cyMin) {
xmin = x;
ymin = y;
xsize = sizeX;
ysize = sizeY;
containerXMax = cxMax;
containerXMin = cxMin;
containerYMax = cyMax;
containerYMin = cyMin;
//
rise = 0;
run = 0;
visible = true;
allowedOffscreen = false;
isSelected = false;
}
public int getXMin() {
return xmin;
}
public int getYMin() {
return ymin;
}
public int getXMax() {
return xmin + xsize;
}
public int getYMax() {
return ymin + ysize;
}
public int getXSize() {
return xsize;
}
public int getYSize() {
return ysize;
}
public Color getColor() {
return color;
}
public boolean getAllowedOffscreen() {
return allowedOffscreen;
}
public boolean getVisible() {
return visible;
}
public int getRun() {
return run;
}
public ImageIcon getGraphic() {
return graphic;
}
public boolean isWithin(int x, int y) {
return x >= xmin && x <= getXMax() && y >= ymin && y <= getYMax();
}
public void setXMin(int x) {
xmin = x;
}
public void setYMin(int y) {
ymin = y;
}
public void setXSize(int x) {
xsize = x;
}
public void setYSize(int y) {
ysize = y;
}
public void setGraphic(String setto) {
try{
graphic = new ImageIcon("setto");
g=graphic.getImage();
System.out.println("tried");
} catch(Exception e){
System.out.println("caught:" + e);
}
}
public void setAllowedOffscreen(boolean allowed) {
allowedOffscreen = allowed;
}
public void setMovement(int riseM, int runM) {
rise = riseM * -1;//rise means to go up, and negative will move it up
run = runM;
}
public void nudge(boolean horizontal, int amount) {
if (horizontal) {
run += amount;
} else {
rise += amount;
}
}
public void setVisible(boolean vis) {
visible = vis;
}
public void setColor(Color c) {
color = c;
}
public boolean checkCollide(OnScreenObject other) {
if (other.getYMax() < getYMin()) { //if other object is above this
return false;
}
if (other.getYMin() > getYMax()) {//if other object is below this
return false;
}
if (other.getXMax() < getXMin()) {//if other is to the left
return false;
}
if (other.getXMin() > getXMax()) {//if other is to the right
return false;
}
return true;
}
public void move() {
if (!allowedOffscreen) {
checkEdge();
}
xmin += run;
ymin += rise;
}
protected abstract void checkEdge();
}
The interactivePanel class is the one that extends JPanel:
package mikeengine;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JPanel;
public class interactivePanel extends JPanel {
ArrayList<OnScreenObject> objects;
IClick myClick;
Ipress myType;
PlayerShip currentShip;
interactivePanel() {
objects = new ArrayList<>();
myClick = new IClick();
myType = new Ipress();
this.addMouseListener(myClick);
this.addKeyListener(myType);
}
#Override
public void paintComponent(Graphics g) {
System.out.println("painting");
paintBackground(g);
paintObjects(g);
checkClick();
checkPress();
}
public void move() {
System.out.println("here2");
checkDeadShip();//also sets current ship
moveObjects();//also removes invisible
checkCollisions();
} // end method move
private void checkClick() {
if (!myClick.getClicked()) {
return;
}
for (int i = 0; i < objects.size(); i++) {
OnScreenObject current = objects.get(i);
if (current.isWithin(myClick.getX(), myClick.getY())) {
System.out.println("CLICKED");
}
}
}
private void paintBackground(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
}
private void paintObjects(Graphics g) {
for (int i = 0; i < objects.size(); i++) {
OnScreenObject current = objects.get(i);
g.setColor(current.getColor());
g.fillOval(current.getXMin(), current.getYMin(), current.getXSize(), current.getYSize());
}
}
public void addObject(OnScreenObject toAdd) {
objects.add(toAdd);
}
private void checkPress() {
if (myType.getDown()) {
objects.get(0).nudge(false, 3);
}
if (myType.getUp()) {
objects.get(0).nudge(false, -3);
}
if (myType.getLeft()) {
objects.get(0).nudge(true, -3);
}
if (myType.getRight()) {
objects.get(0).nudge(true, 3);
}
if (myType.getSpace()) {
fire();
}
}
private void fire() {
OnScreenObject shotBullet = new Bullet(currentShip.getXMax(), ((currentShip.getYMax() - currentShip.getYMin()) / 2) + currentShip.getYMin(), 5, getWidth(), 0, getHeight(), 0);
int shipBonus = 0;
if (currentShip.getRun() > 0) {
shipBonus = currentShip.getRun();
}
shotBullet.setMovement(0, shipBonus + 5);
addObject(shotBullet);
}
private void checkCollisions() {
for (int i = 0; i < objects.size() - 1; i++) {
for (int j = 0; j < objects.size(); j++) {
if (j != i) {
OnScreenObject current = objects.get(i);
OnScreenObject next = objects.get(j);
if (current.checkCollide(next)) {
objects.remove(i);
if (i < j) {
objects.remove(j - 1);
} else {
objects.remove(j);
}
}
}
}
}
}
private void checkDeadShip() {
if (objects.size() > 0) {
try {
currentShip = (PlayerShip) objects.get(0);
} catch (Exception e) {
System.out.println("GAME OVER!");
}
}
}
private void moveObjects() {
for (int i = 0; i < objects.size(); i++) {
OnScreenObject current = objects.get(i);
current.move();
if (!current.getVisible()) {
objects.remove(i);
}
}
}
}
if I do not have that line commented out, the
System.out.println("painting"); inside of my public void paintComponent(Graphics g) is never run, which is why I assume that paintComponent isn't running.
(I cant post images since I don't have 10 rep, but its just a JFrame with the beige empty panel look when it is not commented out).
EDIT:
In your setGraphic() method, replace the line
graphic = new ImageIcon("setto");
with this:
graphic = new ImageIcon(this.getClass()
.getResource(setto));

Java a moving animation (sprite)

Hello i`ve got a problem: when i run this code i get this:
on some java forum they said i need to add Graphics2DObject.clearRect(x1, y1, x2, y2);
(where`s x1 and y1 is coordinates of the image and x2 y2 is width height of the image.) when i add it to the code i get this:
The code(with added function):
Main:
import java.awt.*;
import javax.swing.*;
public class Main {
public static void main(String []args){
Main b = new Main();
b.run();
}
private Sprite sprite;
private Animation a;
private ScreenManager s;
public double sk = 0;
private static final DisplayMode modes1[] = {
new DisplayMode(800, 600, 32, DisplayMode.REFRESH_RATE_UNKNOWN),
};
//load images and add scenes
public void loadImages() {
Image face1 = new ImageIcon("C:\\1.jpg").getImage();
Image face2 = new ImageIcon("C:\\2.jpg").getImage();
a = new Animation();
a.addScene(face1, 50);
a.addScene(face2, 50);
sprite = new Sprite(a);
sprite.setVelocityX(0.3f);
sprite.setVelocityY(0.3f);
}
//main method called from main
public void run() {
s = new ScreenManager();
try {
DisplayMode dm = s.findFirstCompatibleMode(modes1);
s.setFullScreen(dm);
loadImages();
movieLoop();
}finally {
s.restoreScreen();
}
}
//play movie
public void movieLoop() {
long startingTime = System.currentTimeMillis();
long cumTime = startingTime;
while(cumTime - startingTime < 5000) {
long timePassed = System.currentTimeMillis() - cumTime;
cumTime += timePassed;
update(timePassed);
//draw and update the screen
Graphics2D g = s.getGraphics();
draw(g);
g.dispose();
s.update();
try{
Thread.sleep(20);
}catch(Exception ex) {
System.err.println("Error: " + ex);
}
}
}
// Graphics with new function
public void draw(Graphics g) {
g.drawImage(sprite.getImage(), Math.round(sprite.getX()), Math.round(sprite.getY()), null);
if(sk != 1){
g.clearRect(Math.round(sprite.getoX()),Math.round(sprite.getoY()),Math.round(sprite.getWidth()),Math.round(sprite.getHeight()));
}else{
sk = 1;
}
}
//update sprite
public void update(long timePassed) {
if(sprite.getX() < 0) {
sprite.setVelocityX(Math.abs(sprite.getVelocityX()));
} else if (sprite.getX() + sprite.getWidth() >= s.getWidth()) {
sprite.setVelocityX(-Math.abs(sprite.getVelocityX()));
}
if(sprite.getY() < 0) {
sprite.setVelocityY(Math.abs(sprite.getVelocityY()));
} else if (sprite.getY() + sprite.getHeight() >= s.getHeight()) {
sprite.setVelocityY(-Math.abs(sprite.getVelocityY()));
}
sprite.oldX();
sprite.oldY();
sprite.update(timePassed);
}
}
The sprite (movement class):
import java.awt.Image;
public class Sprite {
private Animation a;
private float x;
private float y;
private float vx;
private float vy;
private float ox;
private float oy;
//Constructor
public Sprite(Animation a) {
this.a = a;
}
// Get old x and y to delete them later
public void oldX(){
this.ox = x;
}
public void oldY(){
this.oy = y;
}
public float getoX(){
return ox;
}
public float getoY(){
return oy;
}
//Change position
public void update(long timePassed) {
x += vx * timePassed;
y += vy * timePassed;
a.update(timePassed);
}
//get x position
public float getX() {
return x;
}
//get y position
public float getY() {
return y;
}
//set x position
public void setX(float x) {
this.x = x;
}
//set y position
public void setY(float y) {
this.y = y;
}
// get sprite width
public int getWidth() {
return a.getImage().getWidth(null);
}
// get sprite height
public int getHeight() {
return a.getImage().getHeight(null);
}
//get horizontal velocity
public float getVelocityX() {
return vx;
}
//get vertical velocity
public float getVelocityY() {
return vy;
}
//set horizontal velocity
public void setVelocityX(float vx) {
this.vx = vx;
}
//set vertical velocity
public void setVelocityY(float vy) {
this.vy = vy;
}
//get sprite/image
public Image getImage() {
return a.getImage();
}
}
Screen manager class:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class ScreenManager {
private GraphicsDevice vc;
//Constructor // give vc access to monitor screen
public ScreenManager() {
GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
vc = e.getDefaultScreenDevice();
}
//get all compatible DM's
public DisplayMode[] getCompatibleDisplayModes() {
return vc.getDisplayModes();
}
//compares DM passed in to vc and see if they match
public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) {
DisplayMode goodModes[] = vc.getDisplayModes();
for(int x = 0; x <modes.length; x++){
for(int y = 0; y < goodModes.length; y++){
if(displayModesMatch(modes[x], goodModes[y])) {
return modes[x];
}
}
}
return null;
}
//get current DM
public DisplayMode getCurrentDisplayMode() {
return vc.getDisplayMode();
}
//checks if two modes match each other
public boolean displayModesMatch(DisplayMode m1, DisplayMode m2) {
if(m1.getWidth() != m2.getWidth() || m1.getHeight() != m2.getHeight()) {
return false;
}
if(m1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m1.getBitDepth() != m2.getBitDepth()) {
return false;
}
if(m1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m1.getRefreshRate() != m2.getRefreshRate()) {
return false;
}
return true;
}
//make frame full screen
public void setFullScreen(DisplayMode dm) {
JFrame f = new JFrame();
f.setUndecorated(true);
f.setIgnoreRepaint(true);
f.setResizable(false);
vc.setFullScreenWindow(f);
if(dm != null && vc.isDisplayChangeSupported()) {
try{
vc.setDisplayMode(dm);
}catch(Exception e) {System.out.println("");}
}
f.createBufferStrategy(2);
}
//we will set Graphics object = to this
public Graphics2D getGraphics() {
Window w = vc.getFullScreenWindow();
if(w != null) {
BufferStrategy s = w.getBufferStrategy();
return (Graphics2D)s.getDrawGraphics();
}
else {
return null;
}
}
//updates display
public void update() {
Window w = vc.getFullScreenWindow();
if(w != null) {
BufferStrategy s = w.getBufferStrategy();
if(!s.contentsLost()) {
s.show();
}
}
}
//returns full screen window
public Window getFullScreenWindow() {
return vc.getFullScreenWindow();
}
//get width
public int getWidth() {
Window w = vc.getFullScreenWindow();
if(w != null) {
return w.getWidth();
}
else {
return 0;
}
}
//get height
public int getHeight() {
Window w = vc.getFullScreenWindow();
if(w != null) {
return w.getHeight();
}
else {
return 0;
}
}
//get out of full screen
public void restoreScreen(){
Window w = vc.getFullScreenWindow();
if(w != null) {
w.dispose();
vc.setFullScreenWindow(null);
}
}
//create image compatible with monitor
public BufferedImage createCompatibleImage(int w, int h, int t) {
Window win = vc.getFullScreenWindow();
if(win != null) {
GraphicsConfiguration gc = win.getGraphicsConfiguration();
return gc.createCompatibleImage(w, h, t);
}
return null;
}
}/////////END///////////
Animation class
import java.util.ArrayList;
import java.awt.Image;
public class Animation {
private ArrayList scenes;
private int sceneIndex;
private long movieTime;
private long totalTime;
//Constructor
public Animation() {
scenes = new ArrayList();
totalTime = 0;
start();
}
//add scenes to the array list and set time for each scene
public synchronized void addScene(Image i, long t) {
totalTime += t;
scenes.add(new Onescene(i, totalTime));
}
//start animation from beginning
public synchronized void start() {
movieTime = 0;
sceneIndex = 0;
}
//change scenes
public synchronized void update(long timePassed) {
if(scenes.size() > 1 ) {
movieTime += timePassed;
if(movieTime >= totalTime) {
movieTime = 0;
sceneIndex = 0;
}
while(movieTime > getScene(sceneIndex).endTime) {
sceneIndex++;
}
}
}
//get animations current scene
public synchronized Image getImage() {
if(scenes.size() == 0) {
return null;
}
else {
return getScene(sceneIndex).pic;
}
}
//get scene
private Onescene getScene(int x) {
return (Onescene)scenes.get(x);
}
/////PRIVAT INNER CLASS/////
private class Onescene{
Image pic;
long endTime;
public Onescene(Image pic, long endTime) {
this.pic = pic;
this.endTime = endTime;
}
}
}////END/////
EDIT:
Could someone try running this code ?
Maybe You'll find the mistakes I made...
clearRect goes before drawImage.
I also had a problem with this and you need a "do while loop" in stead of while loop
like this:
do{
Graphics2D g = s.getGraphics();
long timePassed = System.currentTimeMillis() - cumTime;
cumTime += timePassed;
update(timePassed);
//draw and update
draw(g);
g.dispose();
s.update();
try{
Thread.sleep(20);
}catch(Exception ex){
System.out.println("Can't sleep :(");
}
}
while(cumTime - startingTime < 20000); //the Time
And the clearRect must be ABOVE the drawImage
Your loop looks a bit incorrect
Graphics2D g = s.getGraphics();
while(cumTime - startingTime < 5000) {
long timePassed = System.currentTimeMillis() - cumTime;
cumTime += timePassed;
update(timePassed);
//draw and update the screen
draw(g);
g.dispose();
s.update();
try{
Thread.sleep(20);
}catch(Exception ex) {
System.err.println("Error: " + ex);
}
}
}
also try this for your draw method.
// Graphics with new function
public void draw(Graphics g) {
g.clearRect(0,0,800,600);
g.drawImage(sprite.getImage(), Math.round(sprite.getX()), Math.round(sprite.getY()), null);
}

Categories