I have a problem when i compile my code. I want to make my "Win" image to pop up when the score reaches 500 or over, but i get this error:
"incompatible types: int cannot be converted to score"
The problem is under my "private void LevelUp"()"
Here is my code:
import greenfoot.*;
/**
* Write a description of class MinionWorld here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class MinionWorld extends World
{
private long startMillis = 0;
private int numFrames = 0;
private final int groundHeight;
public static final double MAX_FORCE = 11;
public static final double MIN_FORCE = 7;
public static final double GRAVITY = 0.15;
public static final int LOWEST_ANGLE = 30;
private Player[] players;
private int curPlayer;
private int turnCountdown;
private int value;
Score score;
Banan Banan;
private int time, target;
public static int poin, level;
/**
* Constructor for objects of class Banana.
*
*/
public MinionWorld()
{
// Create a new world with 600x400 cells with a cell size of 1x1 pixels.
super(800, 500, 1, false);
groundHeight = 440;
players = new Player[] {new Minion()};
int x = getWidth() / 2;
for (Player p : players)
{
addObject(p, x, groundHeight);
}
curPlayer = 0;
turnCountdown = 10;
time = 1800;
poin = 0;
level = 1;
target = 150;
Greenfoot.setSpeed(50);
prepare();
}
private void showTime()
{
showText("Time: " + time/60, 700, 20);
}
private void showTarget()
{
showText("Target: "+target, 714, 50);
}
private void showLevel()
{
showText("Level: "+level, 50, 20);
}
private void countTime()
{
showTime();
if(time>0)
{
time--;
}
if (time == 0)
{
LevelUp();
}
}
private void lvup()
{
LvlUp LvlUp = new LvlUp();
addObject(LvlUp,400,250);
Greenfoot.delay(200);
removeObject(LvlUp);
}
private void win()
{
Win Win = new Win();
addObject(new Win(),400,250);
Greenfoot.delay(200);
}
public void started()
{
numFrames = 0;
startMillis = System.currentTimeMillis();
}
private double t;
public void act()
{
numFrames += 1;
t = getTimePerFrame();
if (turnCountdown > 0)
{
turnCountdown -= 1;
if (turnCountdown == 0)
{
players[curPlayer].startTurn();
}
}
countTime();
showTarget();
showLevel();
}
public void changeScore(int nilai)
{
if(score!=null)
{
score.setScore(nilai);
}
}
public double getTimePerFrame()
{
return (double)(System.currentTimeMillis() - startMillis) / (1000.0 * (double)(numFrames));
}
public boolean hitsGround(double startX, double startY, double endX, double endY)
{
return endY > groundHeight;
}
public void landed()
{
curPlayer = (curPlayer + 1) % players.length;
turnCountdown = 10;
}
private void LevelUp()
{
{
if(poin>=target)
{
level++;
if (level==2)
{
lvup();
time=1800;
target=350;
}
if (level==3)
{
lvup();
time=1800;
target=500;
}
}
else
{
if (score = 500)
{
Greenfoot.stop();
addObject(new Win(), 400,200);
}
else
{
addObject(new GameOver(),400,200);
addObject(new TryAgain(),360, 320);
addObject(new Exit(),460,320);
}
}
}
}
/**
* Prepare the world for the start of the program. That is: create the initial
* objects and add them to the world.
*/
private void prepare()
{
Menu Menu = new Menu();
Greenfoot.setWorld(Menu);
score = new Score();
Minion Minion = new Minion();
addObject(Minion, 373, 435);
Minion.setLocation(461, 400);
removeObject(Minion);
Evil1 evil1 = new Evil1();
addObject(evil1, 697, 212);
evil1.setLocation(577, 223);
Evil2 evil2 = new Evil2();
addObject(evil2, 259, 58);
evil2.setLocation(695, 63);
evil2.setLocation(693, 53);
Evil3 evil3 = new Evil3();
addObject(evil3, 742, 322);
evil3.setLocation(575, 321);
evil3.setLocation(323, 305);
evil3.setLocation(573, 319);
Evil4 evil4 = new Evil4();
addObject(evil4, 92, 117);
evil4.setLocation(92, 111);
Score score = new Score();
addObject(score, (697), 168);
score.setLocation(757, 247);
score.setLocation(561, 163);
score.setLocation(463, 124);
}
}
Here is my code for my Score class:
import greenfoot.*;
public class Score extends Actor
{
/**
* Act - do whatever the Score wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public Score(){
GreenfootImage gfi = new GreenfootImage(200,200);
gfi.setColor(java.awt.Color.white);
gfi.setFont(new java.awt.Font("Las Vegas",java.awt.Font.PLAIN, 36));
gfi.drawString("0", 30, 30);
setImage(gfi);
}
public void setScore(int score)
{
GreenfootImage gfi = getImage();
gfi.clear();
gfi.drawString(score + "", 30,30);
setImage(gfi);
}
//just a little settlement
public void act()
{
if(MinionWorld.poin>9)
{
setLocation(445, getY());
}
}
}
Code for "move" class:
import greenfoot.*;
/**
* Write a description of class Move here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Move extends Actor
{
int q = 0;
private int Evil = 0;
/**
* Act - do whatever the Fly wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
}
public void flyy()
{
if (getX() == 0 || getX() == 799)
{
setLocation(getX(), 50+Greenfoot.getRandomNumber(320));
turn(180);
this.getImage().mirrorVertically();
q++;
}
}
public void right()
{
move(3/2);
}
public void left()
{
move(-3/2);
}
public void touch1()
{
if(isTouching(Banan.class))
{
MinionWorld MinionWorld = (MinionWorld) getWorld();
MinionWorld.poin = MinionWorld.poin + 10;
MinionWorld.changeScore(MinionWorld.poin);
removeTouching(Evil1.class);
setLocation(799, 50+Greenfoot.getRandomNumber(320));
left();
}
}
public void touch2()
{
if(isTouching(Banan.class))
{
MinionWorld MinionWorld = (MinionWorld) getWorld();
MinionWorld.poin = MinionWorld.poin + 10;
MinionWorld.changeScore(MinionWorld.poin);
removeTouching(Evil2.class);
setLocation(0, 50+Greenfoot.getRandomNumber(320));
right();
}
}
public void touch3()
{
if(isTouching(Banan.class))
{
MinionWorld MinionWorld = (MinionWorld) getWorld();
MinionWorld.poin = MinionWorld.poin + 10;
MinionWorld.changeScore(MinionWorld.poin);
removeTouching(Evil3.class);
setLocation(799, 50+Greenfoot.getRandomNumber(320));
left();
}
}
public void touch4()
{
if(isTouching(Banan.class))
{
MinionWorld MinionWorld = (MinionWorld) getWorld();
MinionWorld.poin = MinionWorld.poin + 10;
MinionWorld.changeScore(MinionWorld.poin);
removeTouching(Evil4.class);
setLocation(0, 50+Greenfoot.getRandomNumber(320));
right();
}
}
public void nulled2()
{
if (getWorld().getObjects(Evil2.class).isEmpty())
{
getWorld().addObject(new Evil2(), 0, 50+Greenfoot.getRandomNumber(320));
right();
}
}
public void nulled4()
{
if (getWorld().getObjects(Evil4.class).isEmpty())
{
getWorld().addObject(new Evil4(), 0, 50+Greenfoot.getRandomNumber(320));
right();
}
}
public void flyback1()
{
if(getX()<-15)
{
setLocation(800, 50+Greenfoot.getRandomNumber(320));
}
if(getX()>815)
{
setLocation(799, 50+Greenfoot.getRandomNumber(320));
turn(180);
this.getImage().mirrorVertically();
}
}
public void flyback2()
{
if(getX()<-35)
{
setLocation(0, 50+Greenfoot.getRandomNumber(320));
turn(180);
this.getImage().mirrorVertically();
}
if(getX()>834)
{
setLocation(0, 50+Greenfoot.getRandomNumber(320));
}
}
}
This is a little bit too long for a comment so I'll post it here.
You are most likely missing the following:
A field in your Score class.
A getter for that field`.
Fixing if (score = 500) and changing it to if (score.getScore() == 500).
So basically:
public class Score extends Actor {
private int score;
public void setScore(int score) {
this.score = score;
...
}
public int getScore() {
return this.score;
}
}
You are missing a score field. Your class should be like this:
public class Score extends Actor
{
private int score;
public int getScore(){
return score;
}
/**
* Act - do whatever the Score wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public Score(){
GreenfootImage gfi = new GreenfootImage(200,200);
gfi.setColor(java.awt.Color.white);
gfi.setFont(new java.awt.Font("Las Vegas",java.awt.Font.PLAIN, 36));
gfi.drawString("0", 30, 30);
setImage(gfi);
}
public void setScore(int score)
{
GreenfootImage gfi = getImage();
gfi.clear();
this.score += score;
gfi.drawString(this.score + "", 30,30);
setImage(gfi);
}
//just a little settlement
public void act()
{
if(MinionWorld.poin>9)
{
setLocation(445, getY());
}
}
}
Then your if should be:
if(score.getScore() == 500){
//doStuff
}
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I keep getting this error in my code. Can someone fix it and how is the code written? Can it be improved by maybe using setters and getters only?
Exception in thread "main" java.lang.NullPointerException
at Player.attack(Player.java:72)
at Main.main(Main.java:15)
My code:
Player.java
public class Player {
String name;
String race;
int hp;
int power;
int armour;
Weapon weapon;
public Player (String n, String r, int h, int p, int a) {
name = n;
race =r;
hp = h;
power = p;
armour = a;
}
public void setName (String n) {
name = n;
}
public String getName() {
return name;
}
public void setRace (String r) {
race = r;
}
public String getRace() {
return race;
}
public void setHP (int h) {
hp = h;
}
public int getHP() {
return hp;
}
public void setPower (int p) {
power = p;
}
public int getPower() {
return power;
}
public void setArmour (int a) {
armour = a;
}
public int getArmour() {
return armour;
}
public boolean dead() {
return hp <= 0;
}
public boolean equip(Weapon weapon) {
this.weapon = weapon;
return true;
}
public boolean receiveDamage(int i) {
if ((hp - i) > 0) {
hp = hp - i;
return true;
}
hp = 0;
return false;
}
public boolean attack(Player player) {
return player.receiveDamage(weapon.useWeapon());
}
}
Main.java
public class Main {
public static void main(String args[]) {
Player Mensch = new Player("Mensch", "Mensch", 85, 12, 10);
Player Ork = new Player("Shrek", "Ork", 50, 14, 6);
Weapon MenschW = new Weapon("mächtiges Schwert", 15, 100);
Weapon OrkW = new Weapon("große Axt", 7, 100);
Mensch.equip(Mensch.weapon);
Ork.equip(Ork.weapon);
while (!Mensch.dead() && !Ork.dead() ) { //Alternativ: for (player hp >=0)
System.out.println("Mensch gegen Ork " + Mensch.attack(Ork));
if (Mensch.dead() || Ork.dead()) {
break;
}
System.out.println("Mensch gegen Ork " + Ork.attack(Mensch));
}
System.out.println("Ork ist tot: " + Ork.dead());
System.out.println("Mensch ist tot: " + Mensch.dead());
}
}
Weapon.java
import java.util.concurrent.ThreadLocalRandom;
public class Weapon {
String name;
int damage;
int hp;
public Weapon(String string, int d, int hp) {
// TODO Auto-generated constructor stub
}
public void setName (String n) {
name = n;
}
public String getName() {
return name;
}
public void setDamage (int d) {
damage = d;
}
public int getDamage() {
return damage;
}
public void setWHP (int h) {
hp = h;
}
public int getWHP() {
return hp;
}
public int useWeapon() {
if
(broken())
return 0;
hp = hp - 5;
return (damage / 2) + random();
}
private int random() {
return ThreadLocalRandom.current().nextInt(1, damage + 1);
}
private boolean broken() {
return hp <= 0;
}
}
I know its a lot of code but I keep getting the same error, also I'm quite new to java so I would appreciate some tips or suggestions to make my code better or more failsave. The code doesn't do much yet but it will (hopefully) be a simple game soon in which two characters fight eachother with some calculations on damageoutput of each player. In this case a Human and Ork. Feel free to try it out
Change
Mensch.equip(Mensch.weapon); // Mensch.weapon is not initialized in constructor so it is null.
Ork.equip(Ork.weapon); // Ork.weapon is not initialized in constructor so it is null as well.
To
// Use your newly created weapons in the main instead.
Mensch.equip(MenschW );
Ork.equip(OrkW);
I'm new to the Android game making scene and for my first game, I made a successful Flappy Bird clone thanks to LibGdx, coffee, and Youtube. To make it NOT be a total clone however, I'm trying to add different types of pipes and this is where I need help with.
I'm trying to make it so that the 4 different types of pipes (or trees, as they are in my game) would appear randomly to make it unpredictable but so far I've only ever managed to make 1 type appear. Here are the codes I used for 2 of the types and for my Play State.
HTree class implementation:
public class HTree {
public static final int TREE_WIDTH = 52;
private static final int FLUCTUACTION = 130;
private static final int TREE_GAP = 100;
private static final int LOWEST_OPENING = 120;
private Texture toptree,bottomtree;
private Vector2 postoptree,posbottree;
private Rectangle boundsTop,boundsBot;
private Random rand;
public HTree(float x){
toptree = new Texture("uppertree.png");
bottomtree = new Texture("bottomtree.png");
rand = new Random();
postoptree = new Vector2(x, rand.nextInt(FLUCTUACTION) + TREE_GAP + LOWEST_OPENING);
posbottree = new Vector2(x, postoptree.y - TREE_GAP - bottomtree.getHeight());
boundsTop = new Rectangle(getPostoptree().x,getPostoptree().y, toptree.getWidth(), toptree.getHeight());
boundsBot = new Rectangle(getPosbottree().x,getPosbottree().y, bottomtree.getWidth(), bottomtree.getHeight());
}
public Texture getToptree() {
return toptree;
}
public Texture getBottomtree() {
return bottomtree;
}
public Vector2 getPostoptree() {
return postoptree;
}
public Vector2 getPosbottree() {
return posbottree;
}
public void reposition(float x){
postoptree.set(x, rand.nextInt(FLUCTUACTION) + TREE_GAP + LOWEST_OPENING);
posbottree.set(x, postoptree.y - TREE_GAP - bottomtree.getHeight());
boundsTop.setPosition(postoptree.x,postoptree.y);
boundsBot.setPosition(posbottree.x,posbottree.y);
}
public boolean collides(Rectangle player){
return player.overlaps(boundsTop) || player.overlaps(boundsBot);
}
public void dispose(){
toptree.dispose();
bottomtree.dispose();
}
}
HTree2 class implementation:
public class HTree2 {
public static final int TREE_WIDTH = 52;
private static final int FLUCTUACTION = 130;
private static final int TREE_GAP = 100;
private static final int LOWEST_OPENING = 120;
private Texture toptree2,bottomtree2;
private Vector2 postoptree2,posbottree2;
private Rectangle boundsTop2,boundsBot2;
private Random rand;
public HTree2(float x){
toptree2 = new Texture("uppertree2.png");
bottomtree2 = new Texture("bottomtree2.png");
rand = new Random();
postoptree2 = new Vector2(x, rand.nextInt(FLUCTUACTION) + TREE_GAP + LOWEST_OPENING);
posbottree2 = new Vector2(x, postoptree2.y - TREE_GAP - bottomtree2.getHeight());
boundsTop2 = new Rectangle(getPostoptree().x,getPostoptree().y, toptree2.getWidth(), toptree2.getHeight());
boundsBot2 = new Rectangle(getPosbottree().x,getPosbottree().y, bottomtree2.getWidth(), bottomtree2.getHeight());
}
public Texture getToptree() {
return toptree2;
}
public Texture getBottomtree() {
return bottomtree2;
}
public Vector2 getPostoptree() {
return postoptree2;
}
public Vector2 getPosbottree() {
return posbottree2;
}
public void reposition2(float x){
postoptree2.set(x, rand.nextInt(FLUCTUACTION) + TREE_GAP + LOWEST_OPENING);
posbottree2.set(x, postoptree2.y - TREE_GAP - bottomtree2.getHeight());
boundsTop2.setPosition(postoptree2.x,postoptree2.y);
boundsBot2.setPosition(posbottree2.x,posbottree2.y);
}
public boolean collides2(Rectangle player){
return player.overlaps(boundsTop2) || player.overlaps(boundsBot2);
}
public void dispose2(){
toptree2.dispose();
bottomtree2.dispose();
}
}
HPlayState class implementation:
public class HPlayState extends HState {
private static final int TREE_SPACING = 125;
private static final int TREE_COUNT = 4;
private static final int GROUND_Y_OFFSET = -50;
private HBird bird;
private Texture bg;
private Texture ground;
private Vector2 groundPos1,groundPos2;
private Array<HTree> trees;
private Array<HTree2> trees2;
public HPlayState(HGameStateManager gsm) {
super(gsm);
bird = new HBird(50,300);
cam.setToOrtho(false, HBonGame.WIDTH/2,HBonGame.HEIGHT/2);
bg = new Texture("background3.jpg");
ground = new Texture("ground.png");
groundPos1 = new Vector2(cam.position.x-cam.viewportWidth/2,GROUND_Y_OFFSET);
groundPos2 = new Vector2((cam.position.x-cam.viewportWidth/2) + ground.getWidth(),GROUND_Y_OFFSET);
trees = new Array<HTree>();
trees2 = new Array<HTree2>();
for(int i=1; i <= TREE_COUNT; i++){
trees.add(new HTree(i * (TREE_SPACING + HTree.TREE_WIDTH)));
}
for (int i=1; i >= TREE_COUNT; i++){
trees2.add(new HTree2(i * (TREE_SPACING + HTree2.TREE_WIDTH)));
}
}
#Override
protected void handleInput() {
if (Gdx.input.justTouched())
bird.jump();
}
#Override
public void update(float dt) {
handleInput();
updateGround();
bird.update(dt);
cam.position.x = bird.getPosition().x + 80;
for (int i=0; i < trees.size; i++ ){
HTree tree = trees.get(i);
if (cam.position.x - (cam.viewportWidth / 2) > tree.getPostoptree().x + tree.getToptree().getWidth()){
tree.reposition(tree.getPostoptree().x + ((HTree.TREE_WIDTH + TREE_SPACING) * TREE_COUNT));
}
if(tree.collides(bird.getBounds())){
gsm.set(new HGameOverState(gsm));
}
}
for (int i=0; i < trees2.size; i++ ){
HTree2 tree2 = trees2.get(i);
if (cam.position.x - (cam.viewportWidth / 2) > tree2.getPostoptree().x + tree2.getToptree().getWidth()){
tree2.reposition2(tree2.getPostoptree().x + ((HTree2.TREE_WIDTH + TREE_SPACING) * TREE_COUNT));
}
if(tree2.collides2(bird.getBounds())){
gsm.set(new HGameOverState(gsm));
}
}
if (bird.getPosition().y <= ground.getHeight()+GROUND_Y_OFFSET){
gsm.set(new HGameOverState(gsm));
}
cam.update();
}
#Override
public void render(SpriteBatch sb) {
sb.setProjectionMatrix(cam.combined);
sb.begin();
sb.draw(bg,cam.position.x - (cam.viewportWidth/2), 0);
sb.draw(bird.getTexture(),bird.getPosition().x,bird.getPosition().y);
for (HTree tree : trees) {
sb.draw(tree.getToptree(), tree.getPostoptree().x, tree.getPostoptree().y);
sb.draw(tree.getBottomtree(), tree.getPosbottree().x, tree.getPosbottree().y);
}
for (HTree2 tree2 : trees2) {
sb.draw(tree2.getToptree(), tree2.getPostoptree().x, tree2.getPostoptree().y);
sb.draw(tree2.getBottomtree(), tree2.getPosbottree().x, tree2.getPosbottree().y);
}
sb.draw(ground, groundPos1.x,groundPos1.y);
sb.draw(ground, groundPos2.x,groundPos2.y);
sb.end();
}
#Override
public void dispose() {
bg.dispose();
bird.dispose();
ground.dispose();
for (HTree tree : trees){
tree.dispose();
}
for (HTree2 tree2 : trees2){
tree2.dispose2();
}
}
private void updateGround() {
if (cam.position.x - (cam.viewportWidth / 2) > groundPos1.x + ground.getWidth())
groundPos1.add(ground.getWidth() * 2, 0);
if (cam.position.x - (cam.viewportWidth / 2) > groundPos2.x + ground.getWidth())
groundPos2.add(ground.getWidth() * 2, 0);
}
#Override
public void resize(int width, int height) {
bird = new HBird(50,300);
}
}
I would recommend using an interface or a superclass of type HTree which all the other types can then extend from. E.g.
public abstract class HTree {
/*
All your class variables as declared
in your question
*/
public HTree(float x, String topTreeFile, String bottomTreeFile) {
/* Do all the setup stuff here */
// Set the textures
toptree = new Texture(topTreeFile);
bottomtree = new Texture(bottomTreeFile);
}
/*
All your normal getters and setters
and other functions here
*/
}
Then you would create 4 different classes which all extend from HTree as follows:
/* Different types of tree each extend the main HTree class */
public class HTree1 extends HTree {
public HTree1(float x) {
super(x, "uppertree.png", "lowertree.png");
/* Any other custom code for this tree type
can go here */
}
}
public class HTree2 extends HTree {
public HTree1(float x) {
super(x, "uppertree2.png", "lowertree2.png");
/* Any other custom code for this tree type
can go here */
}
}
/* And so on for HTree3 and HTree4 ... */
Finally, you can use any of these four different types as a HTree because they all extend from that class so they can be grouped into a single Array<HTree> and can be rendered/updated together in a single loop.
public class HPlayState extends HState {
/* Other class variables here ... */
/* Only one array for all different tree types */
private Array<HTree> trees;
public HPlayState(GameStateManager gsm) {
/* Same setup code ... */
trees = new Array<HTree>();
Random random = new Random();
for (int i = 1; i <= TREECOUNT; i++) {
/* Randomly pick which tree type to choose */
int treeType = rand.next(4); // 4 or however many different types of tree you have
float x = i * (TREE_SPACING + HTree.TREE_WIDTH);
if (treeType == 0) trees.add(new HTree1(x));
else if (treeType == 1) trees.add(new HTree2(x));
else if (treeType == 2) trees.add(new HTree3(x));
else trees.add(new HTree4(x));
}
}
/*
Rendering and updating code here
*/
}
Note: I haven't tested any of the code so there a might be a few typos or changes needed but it should work fine.
In the showDebugWindow() method inside a class I called, [TinyDebug], the JOptionPane.showInputDialog() is called twice even after I input the correct password, why is that?
Additionally, this code is being executed from an update() method in my Game class, which is called once every second.
Take a look below at the following sets of code for the problem.
Game:
public class Game extends TinyPixel {
private static Game game;
private static KeyManager keyManager;
private static MouseManager mouseManager;
private static GameStateManager sManager;
private boolean isRunning;
private int targetTime;
private final int frameCap = 60;
public Game(String gameTitle, String gameVersion, int gameWidth, int gameRatio, int gameScale) {
super(gameTitle, gameVersion, gameWidth, gameRatio, gameScale);
init();
}
public void init() {
Utilities.printMessage("\t\t-[" + Library.gameTitle + "]-" +
"\n[Game Version]: " + gameVersion +
"\n[Unique Build Number]: " + Utilities.generateCode(16));
ResourceLoader.loadImages();
ResourceLoader.loadMusic();
ResourceLoader.loadSound();
ResourceLoader.loadFonts();
keyManager = new KeyManager(this);
mouseManager = new MouseManager(this);
sManager = new GameStateManager(this);
}
#Override public void update() {
sManager.update();
mouseManager.update();
}
#Override public void render() {
BufferStrategy bs = tinyWindow.getCanvas().getBufferStrategy();
if (bs == null) {
tinyWindow.getCanvas().createBufferStrategy(3);
tinyWindow.getCanvas().requestFocus();
return;
}
Graphics g = bs.getDrawGraphics();
g.clearRect(0, 0, gameWidth, gameHeight);
sManager.render(g);
g.dispose();
bs.show();
}
public void start() {
if(isRunning) return;
isRunning = true;
new Thread(this, gameTitle + " " + gameVersion).start();
}
public void stop() {
if(!isRunning) return;
isRunning = false;
}
#Override public void run() {
isRunning = true;
targetTime = 1000 / frameCap;
long start = 0;
long elapsed = 0;
long wait = 0;
while (isRunning) {
start = System.nanoTime();
update();
render();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if (wait < 0) wait = 5;
try {
Thread.sleep(wait);
} catch (InterruptedException e) {
Utilities.printErrorMessage("Failed to Load " + gameTitle + " " + gameVersion);
}
}
stop();
}
public static KeyManager getKeyManager() {
return keyManager;
}
public static GameStateManager getsManager() {
return sManager;
}
public static Game getGame() {
return game;
}
}
GameLauncher:
public class GameLauncher {
public static void main(String[] args) {
new Game(Library.gameTitle, Library.gameVersion, 640, TinyPixel.Square, 1).start();
}
}
GameStateManager:
public class GameStateManager {
private int numStates = 3;
public static final int MenuState = 0;
public static final int LoadingState = 1;
public static final int GameState = 2;
public static GameState[] gStates;
private static int currentState;
private static String currentMusic;
protected Game game;
public GameStateManager(Game game) {
this.game = game;
init();
}
private void init() {
gStates = new GameState[numStates];
currentState = MenuState;
//currentMusic = Library.backgroundMusic;
//TinyPlayer.playMusic(currentMusic);
loadState(currentState);
}
private void loadState(int gState) {
if (gState == MenuState) gStates[gState] = new MenuState(game, this);
if (gState == LoadingState) gStates[gState] = new LoadingState(game, this);
if (gState == GameState) gStates[gState] = new PlayState(game, this);
}
private void unloadState(int gState) {
gStates[gState] = null;
}
public void setState(int gState) {
unloadState(gState);
currentState = gState;
loadState(gState);
}
private void changeMusic(String key) {
if (currentMusic.equals(key)) return;
TinyPlayer.stopMusic(currentMusic);
currentMusic = key;
TinyPlayer.loop(currentMusic);
}
public void update() {
try {
gStates[currentState].update();
} catch (Exception e) {}
}
public void render(Graphics g) {
try {
gStates[currentState].render(g);
} catch (Exception e) {}
}
public static int getCurrentState() {
return currentState;
}
}
GameState:
public abstract class GameState {
protected Game game;
protected GameStateManager sManager;
public GameState(Game game, GameStateManager sManager) {
this.game = game;
this.sManager = sManager;
init();
}
public abstract void init();
public abstract void update();
public abstract void render(Graphics g);
}
MenuState:
public class MenuState extends GameState {
private Rectangle playBtn, exitBtn;
private TinyDebug tinyDebug;
public static final Color DEFAULT_COLOR = new Color(143, 48, 223);
public MenuState(Game game, GameStateManager sManager) {
super(game, sManager);
init();
}
public void init() {
tinyDebug = new TinyDebug();
int xOffset = 90, yOffset = 70;
playBtn = new Rectangle(Game.getWidth() / 2 - xOffset, Game.getHeight() / 2, 180, 40);
exitBtn = new Rectangle(Game.getWidth() / 2 - xOffset, Game.getHeight() / 2 + yOffset, 180, 40);
}
public void update() {
if (Game.getKeyManager().debug.isPressed()) {
Game.getKeyManager().toggleKey(KeyEvent.VK_Q, true);
tinyDebug.showDebugWindow();
}
if (Game.getKeyManager().space.isPressed()) {
Game.getKeyManager().toggleKey(KeyEvent.VK_SPACE, true);
sManager.setState(GameStateManager.LoadingState);
}
if (Game.getKeyManager().exit.isPressed()) {
Game.getKeyManager().toggleKey(KeyEvent.VK_ESCAPE, true);
System.exit(0);
}
}
public void render(Graphics g) {
//Render the Background
g.drawImage(Library.menuBackground, 0, 0, Game.getWidth(), Game.getHeight(), null);
//Render the Game Version
TinyFont.drawFont(g, new Font(Library.gameFont, Font.PLAIN, 8), Color.white, "Version: " + Library.gameVersion, Game.getWidth() / 2 + 245, Game.getHeight() - 30);
//Render the Social Section
TinyFont.drawFont(g, new Font(Library.gameFont, Font.PLAIN, 8), Color.white, "#nickadamou", 20, Game.getHeight() - 60);
TinyFont.drawFont(g, new Font(Library.gameFont, Font.PLAIN, 8), Color.white, "#nicholasadamou", 20, Game.getHeight() - 45);
TinyFont.drawFont(g, new Font(Library.gameFont, Font.PLAIN, 8), Color.white, "Ever Tried? Ever Failed? No Matter. Try Again. Fail Again. Fail Better.", 20, Game.getHeight() - 30);
//Render the Debug Section
tinyDebug.renderDebug(g);
g.setColor(Color.white);
g.drawRect(playBtn.x, playBtn.y, playBtn.width, playBtn.height);
g.drawRect(exitBtn.x, exitBtn.y, exitBtn.width, exitBtn.height);
TinyFont.drawFont(g, new Font(Library.gameFont, Font.PLAIN, 14), Color.white, "Play Game [space]", playBtn.x + 10, playBtn.y + 25);
TinyFont.drawFont(g, new Font(Library.gameFont, Font.PLAIN, 14), Color.white, "Exit Game [esc]", exitBtn.x + 20, exitBtn.y + 25);
}
}
keyManager:
public class KeyManager implements KeyListener {
private Game game;
public KeyManager(Game game) {
this.game = game;
game.getTinyWindow().getCanvas().addKeyListener(this);
}
public class Key {
private int amtPressed = 0;
private boolean isPressed = false;
public int getAmtPressed() {
return amtPressed;
}
public boolean isPressed() {
return isPressed;
}
public void toggle(boolean isPressed) {
this.isPressed = isPressed;
if (isPressed) amtPressed++;
}
}
public Key up = new Key();
public Key down = new Key();
public Key left = new Key();
public Key right = new Key();
public Key space = new Key();
public Key debug = new Key();
public Key exit = new Key();
public void keyPressed(KeyEvent key) {
toggleKey(key.getKeyCode(), true);
}
public void keyReleased(KeyEvent key) {
toggleKey(key.getKeyCode(), false);
}
public void keyTyped(KeyEvent e) {}
public void toggleKey(int keyCode, boolean isPressed) {
game.getTinyWindow().getFrame().requestFocus();
game.getTinyWindow().getCanvas().requestFocus();
if (keyCode == KeyEvent.VK_W || keyCode == KeyEvent.VK_UP) {
up.toggle(isPressed);
}
if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN) {
down.toggle(isPressed);
}
if (keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT) {
left.toggle(isPressed);
}
if (keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT) {
right.toggle(isPressed);
}
if (keyCode == KeyEvent.VK_SPACE) {
space.toggle(isPressed);
}
if (keyCode == KeyEvent.VK_Q) {
debug.toggle(isPressed);
}
if (keyCode == KeyEvent.VK_ESCAPE) {
exit.toggle(isPressed);
}
}
#SuppressWarnings("unused")
private void debug(KeyEvent key) {
System.out.println("[keyCode]: " + key.getKeyCode());
}
}
TinyDebug:
public class TinyDebug {
private final String appTitle = Library.gameTitle;
private String tinyPassword, tinyBuildCode;
private boolean isAllowedDebugging = false;
private boolean isShowingTinyText = false;
public TinyDebug() {
tinyPassword = "test123"; // - Standard Password (Non-Renewable)
//tinyPassword = Utilities.generateCode(16); // - Stronger Password (Renewable)
writePasswordToFile(tinyPassword);
tinyBuildCode = Utilities.generateCode(16);
}
//TODO: This method invokes JOptionPane.showInputDialog() twice even after I input the correct password, why?
public void showDebugWindow() {
boolean hasRun = true;
if (hasRun) {
Clipboard cBoard = Toolkit.getDefaultToolkit().getSystemClipboard();
cBoard.setContents(new StringSelection(tinyPassword), null);
if (isAllowedDebugging() && isShowingTinyText()) return;
String userPassword = JOptionPane.showInputDialog("Input Password to Enter [TinyDebug].");
do {
if (userPassword.equals(tinyPassword)) {
JOptionPane.showMessageDialog(null, "[" + appTitle + "]: The Password Entered is Correct.", appTitle + " Message", JOptionPane.PLAIN_MESSAGE);
isAllowedDebugging(true);
isShowingTinyText(true);
break;
} else {
JOptionPane.showMessageDialog(null, "[Error Code]: " + Utilities.generateCode(16) + "\n[Error]: Password is Incorrect.", appTitle + " Error Message", JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
} while (userPassword != null || userPassword.trim().isEmpty() != true);
}
hasRun = false;
}
#SuppressWarnings("unused")
public void renderDebug(Graphics g) {
if (isAllowedDebugging()) {
//TODO: Render Debug Information.
TinyFont.drawFont(g, new Font(Library.gameFont, Font.PLAIN, 8), Color.white, "Tiny Pixel [Debug]", 5, 10);
TinyFont.drawFont(g, new Font(Library.gameFont, Font.PLAIN, 8), Color.white, "#. [Options are Shown Here]", 10, 25);
if (isShowingTinyText()) {
String debugHeader = appTitle + " Information";
String debugPasswordField = appTitle + " Information:";
String debugBuildNumber = appTitle + " Unique Build #: " + getTinyBuildCode();
}
}
}
//TODO: This method prints the [Utilities.printMessage(appTitle + ": [tinyPassword] Generated and Stored # FilePath: \n" + logFile.getAbsolutePath());] twice, why?
private void writePasswordToFile(String tinyPassword) {
BufferedWriter bWriter = null;
try {
File logFile = new File("tinyPassword.txt");
Utilities.printMessage(appTitle + ": [tinyPassword] Generated and Stored # FilePath: \n" + logFile.getAbsolutePath());
bWriter = new BufferedWriter(new FileWriter(logFile));
bWriter.write(appTitle + " debug Password: " + tinyPassword);
} catch (Exception e) {
Utilities.printErrorMessage("Failed to Write [tinyPassword] to File.");
} finally {
try {
bWriter.close();
} catch (Exception e) {
Utilities.printErrorMessage("Failed to Close [bWriter] Object.");
}
}
}
public String getTinyPassword() {
return tinyPassword;
}
public String getTinyBuildCode() {
return tinyBuildCode;
}
public void isShowingTinyText(boolean isShowingTinyText) {
this.isShowingTinyText = isShowingTinyText;
}
public boolean isShowingTinyText() {
return isShowingTinyText;
}
public void isAllowedDebugging(boolean isAllowedDebugging) {
this.isAllowedDebugging = isAllowedDebugging;
if (isAllowedDebugging) showDebugWindow();
}
public boolean isAllowedDebugging() {
return isAllowedDebugging;
}
}
In showDebugWindow() method, you have this statement:
if (userPassword.equals(tinyPassword)) {
...
isAllowedDebugging(true); // Problematic statement
...
}
Which calls this method:
public void isAllowedDebugging(boolean isAllowedDebugging) {
this.isAllowedDebugging = isAllowedDebugging;
if (isAllowedDebugging) showDebugWindow(); // Second call?
}
As you see, when you set isAllowedDebugging switch, you also call the method, so when you enter password correct, this second call happens.
was wondering how is it possible to get stepProgram(); to work on my gui,
many thanks!
This is GUI Class:
package maskin;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class mGUI extends JFrame implements ActionListener {
private JButton knapp;
private JTextField instruksjona, PCa, RAMa;
private int l;
public M instruksjon, PC, RAM[], R;
private M maskin;
M mObject = new M();
public static void main(String[] args) {
mGUI vindu = new mGUI();
vindu.setTitle("Maskin");
vindu.setDefaultCloseOperation(EXIT_ON_CLOSE);
vindu.opprettGUI();
vindu.setSize(600, 600);
vindu.pack();
vindu.setVisible(true);
}
public void getValue(){
}
public void opprettGUI() {
setLayout(new FlowLayout());
JPanel knappePanel = new JPanel();
JButton knapp = new JButton("Step PROGRAM");
knappePanel.add(knapp);
knapp.addActionListener(this);
//knapp.addActionListener(this);
//M reg = new R(R);
instruksjona = new JTextField(10);
add(instruksjona);
PCa = new JTextField(10);
add(PCa);
RAMa = new JTextField(10);
add(RAMa);
add(knapp);
}
#Override
public void actionPerformed(ActionEvent e) {
instruksjona.setText("3" );
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
This is code containing stepProgram:
package maskin;
import java.io.*;
import java.util.*;
import static javax.swing.JOptionPane.*;
import static java.lang.Integer.*;
public class M extends Object {
private static final int IREAD = 10; // Flere ...
private final int RAM_SIZE = 256;
private int[] RAM = new int[RAM_SIZE]; // Eller holder det med en byte-array?
private int R; // Register
private int PC = 0; // Programteller
private int instruksjon = RAM[PC];
// Flere instansvariabler?
public M(int R, int PC, int instruksjon, int[] RAM) {
this.RAM = RAM;
this.PC = PC;
this.R = R;
this.instruksjon = instruksjon;
/*
* Initialisering av instansvariabler
*/
}
public M() {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void setVerdi(int R, int PC, int instruksjon, int[] RAM) {
this.R = R;
this.PC = PC;
this.instruksjon = instruksjon;
this.RAM = RAM;
}
public int getR(){
return R;
}
public int getPC(){
return PC;
}
public int getInstruksjon(){
return instruksjon;
}
public int[] getRAM(){
return RAM;
}
public int lesInn() {
String tallTxt = showInputDialog("Skriv inn helltall:");
int tall = parseInt(tallTxt);
return tall;
}
public void loadProgram(String fileName) {
try {
File test1 = new File(fileName);
Scanner leser = new Scanner(test1);
int i = 0;
while (leser.hasNextLine()) {
String linje = leser.nextLine();
String[] splitter = linje.split(" ");
RAM[i] = Integer.parseInt(splitter[0]);
if (splitter.length > 1) {
RAM[i + 1] = Integer.parseInt(splitter[1]);
}
i += 2;
}
leser.close();
} catch (IOException e1) {
System.out.println("FEIL" + e1.toString());
}
//visMemory();
/*
* Nullstill instansvariabler Åpne fil Les inn program fra fil, linje
* for linje Lukk fil
*/
}
public void visMemory() {
for (int i = 0; i < RAM.length; i++) {
System.out.println(RAM[i]);
}
}
public void stepProgram() {
int instruksjon = RAM[PC];
int verdi = RAM[PC + 1];
if (instruksjon == 10) {
String tallTxt = showInputDialog("Skriv inn helltall:");
int tall = parseInt(tallTxt);
R = tall;
PC += 2;
} else if (instruksjon == 11) {
showMessageDialog(null, "Helltall er: " + R);
PC += 2;
} else if (instruksjon == 12){
String ta = showInputDialog(null, "Skriv inn tall");
RAM[verdi] = Integer.parseInt(ta);
PC +=2;
} else if (instruksjon == 20) {
R = RAM[verdi];
PC += 2;
} else if (instruksjon == 21) {
RAM[verdi] = R;
PC += 2;
} else if (instruksjon == 22) {
R = verdi;
PC += 2;
} else if (instruksjon == 30) {
R += RAM[verdi];
PC += 2;
}else if(instruksjon == 31){
R -= RAM[verdi];
PC +=2;
}else if(instruksjon == 32){
R *= RAM[verdi];
PC+=2;
}else if (instruksjon == 33) {
R /= RAM[verdi];
PC+= RAM[verdi];
} else if (instruksjon == 40) {
PC = verdi;
} else if (instruksjon == 42) {
if (R == 0) {
PC = verdi;
} else {
PC += 2;
}
} else if (instruksjon == 50) {
System.exit(0);
}
System.out.println("Dette er instruksjon: " + instruksjon);
System.out.println("Dette er register: " + R);
System.out.println("Dette er programteller: " + PC);
/*
* Les neste instruksjon fra RAM Utfør instruksjonen (og oppdater
* programtelleren)
*/
}
public void executeProgram() {
while (true) {
stepProgram();
}
/*
* Så lenge programmet ikke er avsluttet Utfør neste instruksjon
* (stepProgram) Vis avsluttende melding
*/
}
public static void main(String[] args) {
M maskin = new M();
maskin.loadProgram("navn.txt");
maskin.stepProgram();
/*
* Hent filnavn fra kommandolinje (args[0]) Lag et M-objekt Last program
* fra fil (loadProgram) Utfør programmet (executeProgram)
*/
}
void setText(String antall_klikk__) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
/*
* Eventuelle hjelpemetoder
*/
I want to make button stepProgram to put all the numbers that on System out println in M class.
To call stepProgram() on mObject:
mObject.stepProgram();
Im trying to animate 2 boxes to go from the top right to the bottom left of a JPanel. For the animation I'm using a Swing Timer and SwingUtilities.invokeLater(). The problem is that when I click the start button. It only animates and moves the blue box, but not the red one.
Heres the code:
//import neccessary stuff
public class Example extends JFrame {
public static void main(String[] args) {
Example e = new Example();
e.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
e.setSize(600, 565);
e.setVisible(true);
}</code>
private JButton startButton = new JButton("Start");
private JPanel theTable = new table();
public Example() {
add(startButton, BorderLayout.SOUTH);
add(theTable, BorderLayout.CENTER);
Handler handler = new Handler();
startButton.addActionListener(handler);
}
public ArrayList<Integer> xPos, yPos;
final int START_POSITION_X = 470;
final int START_POSITION_Y = 10;
final int[] END_POSITION_X = {70, 87};
final int END_POSITION_Y = 160;
private class table extends JPanel {
public table() {
xPos = new ArrayList<Integer>();
yPos = new ArrayList<Integer>();
xPos.add(START_POSITION_X); //default position for box1
yPos.add(START_POSITION_Y);
xPos.add(START_POSITION_X); //default position for box2
yPos.add(START_POSITION_Y);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(new Color(-16756217));
g.setColor(Color.RED);
g.fillRect(xPos.get(1), yPos.get(1), 89, 129);
g.setColor(Color.BLUE);
g.fillRect(xPos.get(0), yPos.get(0), 89, 129);
if (isAnimating) {
animator.start();
} else {
animator.stop();
isAnimating = false;
}
}
}
private class Handler implements ActionListener {
public void actionPerformed(ActionEvent e) {
Runnable r1 = new Runnable() {
#Override
public void run() {
animateCard(0, END_POSITION_X[0], END_POSITION_Y);
}
};
SwingUtilities.invokeLater(r1);
animateCard(1, END_POSITION_X[1], END_POSITION_Y);
}
}
public void animateCard(int card, int xDest, int yDest) {
cardID = card;
xDestination = xDest;
yDestination = yDest;
totalXDistance = Math.abs(xDestination - START_POSITION_X);
totalYDistance = Math.abs(yDestination - START_POSITION_Y);
animator.start();
}
int cardID;
int xDestination, yDestination, totalXDistance, totalYDistance;
boolean isAnimating = false;
Timer animator = new Timer(15, new ActionListener() {
int startVel = 20;
public void actionPerformed(ActionEvent e) {
double xRelDistance, xAbsDistance, xVel;
int xRealVel;
xAbsDistance = xDestination - xPos.get(cardID);
xRelDistance = xAbsDistance / totalXDistance;
xVel = startVel * xRelDistance;
double yRelDistance, yAbsDistance, yVel;
yAbsDistance = yDestination - yPos.get(cardID);
yRelDistance = yAbsDistance / totalYDistance;
yVel = startVel * yRelDistance;
if (xVel > 0) {
xRealVel = (int) java.lang.Math.ceil(xVel);
} else {
xRealVel = (int) java.lang.Math.floor(xVel);
}
xPos.set(cardID, xPos.get(cardID) + xRealVel);
int yRealVel;
if (xVel > 0) {
yRealVel = (int) java.lang.Math.ceil(yVel);
yPos.set(cardID, yPos.get(cardID) + yRealVel);
} else {
yRealVel = (int) java.lang.Math.floor(yVel);
}
yPos.set(cardID, yPos.get(cardID) + yRealVel);
if ((xPos.get(cardID) == xDestination) && (yPos.get(cardID) == yDestination)) {
isAnimating = false;
} else {
isAnimating = true;
}
repaint();
}
});
}
So all of those variable declared at the class level are shared... Your first call to animateCard will set them and then your second call to animateCard is going to completely overwrite the previous values. You need to change them from class variables to parameters of the animation.
Create a new class AnimationTask that implements ActionListener and save the variables in that class.
E.g.,
class AnimationTask implements ActionListener {
private int cardID;
private int xDest;
private int yDest;
private int totalXDistance;
private int totalYDistance;
public AnimationTask(int cardID, int xDest, int yDest) {
this.cardID = cardID;
this.xDest = xDest;
this.yDest = yDest;
this.totalXDistance = Math.abs(xDestination - START_POSITION_X);
this.totalYDistance = Math.abs(yDestination - START_POSITION_Y);
}
public void actionPerformed(ActionEvent e) {
// do your animation logic...
}
}
and use that custom class in your "animator"
E.g.,
Timer animator = new Timer(15, new AnimationTask(cardId, xDest, yDest);
put
animateCard(1, END_POSITION_X[1], END_POSITION_Y);
inside your run method:
public void run() {
animateCard(0, END_POSITION_X[0], END_POSITION_Y);
}