This is a "tower defense" game. I have a class called soldier.
if(wave1==true){
for(int i=0;i<(wave*10);i++){
handler.addObject(new soldier(getX(), getY(), ID.soldier, handler));
try {
// System.out.println(i);
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
wave++;
wave1=false;
try {
// System.out.println(i);
Thread.sleep(WT);
} catch (InterruptedException e) {
}
}
Every time this code is called is the soldier gets spawned 10 times for every wave, but I have one issue. I would like the tower 1 to kill the furthest soldier in range. The code for the killing:
private void collision() {
for(int i=0; i< Handler.object.size();i++){
GameObject tempObject = Handler.object.get(i);
if(tempObject.getID()== ID.ST1){
if(getBounds().intersects(tempObject.getBounds())){
Hsol=(Hsol-1);
if(Hsol<=0){
handler.removeObject(this);
}
}
}
}
}
So I know I need to do a distance formula to find which ones closer, but I'm not sure how to do that.
Given two points (x1, y1) and (x2, y2), the distance formula is
√[(x1-x2)^2 + (y1-y2)^2]
So, using that formula, you can loop through each soldier and see which one is closest to the point that the attack is coming from.
private void collision() {
for(int i=0; i< Handler.object.size();i++){
GameObject tempObject = Handler.object.get(i);
if(tempObject.getID()== ID.ST1){
if(this==handler.object.get(3)){
if(getBounds().intersects(tempObject.getBounds())){
Hsol=(Hsol-1);
if(Hsol<=0){
handler.removeObject(this);
HUD.coin=(HUD.coin+100);
instances=(instances-1);
//System.out.println(HUD.coin);
}
}
}
}
}
}
Related
I am creating a tic tac toe game but in this case, it is more than two players. I am completely unsure how to go about this and had many iterations. It is done via JButtons gridlayout. For normal tictactoe, it works just fine:
buttons[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for(int i=0;i<9;i++) {
if(e.getSource()==buttons[i]) {
if(pTurn) {
if(buttons[i].getText()=="") {
buttons[i].setForeground(new Color(255,0,0));
buttons[i].setText("X");
pTurn=false;
txt.setText("O turn");
checkCondition();
}
}
else {
if(buttons[i].getText()=="") {
buttons[i].setForeground(new Color(0,0,255));
buttons[i].setText("O");
pTurn=true;
txt.setText("X turn");
checkCondition();
}
}
}
}
}
});
However, my implementation of 3+ players is not working. My logic is skewed but I am unsure where.
buttons[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for(int i=0;i<size;i++) {
if(e.getSource()==buttons[i]) {
for (int k = 0; k < col_row; k++ ) {
for (int j = k+1; j < col_row; j++) {
if (players[k]) {
if(buttons[i].getText()=="") {
buttons[i].setForeground(new Color(0,0,255));
buttons[i].setText(pIcon[k]);
players[k]=false;
txt.setText(pIcon[j] + " turn");
checkCondition();
}
}
else {
if(buttons[i].getText()=="") {
buttons[i].setForeground(new Color(0,0,255));
buttons[i].setText(pIcon[j]);
players[k]=true;
txt.setText(pIcon[j+1] + " turn");
checkCondition();
}
}
}
}
}
}
}
});
In this case, col_row is just the number of players. Players[] is an array of boolean players. My logic is that its checked to see if they have went but it doesn't work really.
pIcon[] is an array of player characters (X,O,A,B,C...). I am not really sure how to fix this.
Two player logic (as implemented)
mark first active player
on click iterate over all fields until clicked field is identified
if it is player A's turn do player A turn else do player B turn
n player logic (according to your boolean array idea)
mark first active player in boolean array
on click iterate over all fields until clicked field is identified
iterate over all players until active player k is found then do player k turn and mark next active player j = (k+1) modulo number of players
buttons[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for(int i=0;i<size;i++) {
if(e.getSource()==buttons[i]) {
// iterate over players to find next active player
for (int k = 0; k < 3; k++ ) { // 3 players
if (players[k]) {
// next active player found
if(buttons[i].getText()=="") {
buttons[i].setForeground(new Color(0,0,255));
buttons[i].setText(pIcon[k]);
players[k]=false;
int j = (k + 1) % 3; // index for next active player
players[j] = true; // mark next active player
txt.setText(pIcon[j] + " turn");
checkCondition();
break; // leave inner loop
}
}
}
}
}
}
}
});
I'm coding a rescue simulation program and while applying the required tests it keeps giving a failure saying that the number of occupants remaining in the building is not correctly calculated and I can't figure out why!
below i provided the two methods that are supposed to give back the number of occupants.
Thanks in advance!
public void treat(){
boolean f=false;
if(!f){
((Disaster)((Citizen)this.getTarget()).getDisaster()).setActive(false);
ResidentialBuilding r= (ResidentialBuilding)this.getTarget();
if(r.getOccupants().size()!=0){
for(int i=0;i<r.getOccupants().size();i++){
if(this.getPassengers().size()<=this.getMaxCapacity()){
f=true;
Citizen z=(Citizen)r.getOccupants().get(i);
if(z.getState()!=CitizenState.DECEASED){
r.getOccupants().remove(i);
this.getPassengers().add(z);
}
}
}
}
else{
this.setState(UnitState.IDLE);
this.jobsDone();
}
}
else
this.cycleStep();
}
public void cycleStep(){
if(super.getDistanceToBase()==0)
super.getWorldListener().assignAddress(this, 0, 0);
if(super.getTarget()!=null){
if(this.getLocation()== this.getTarget().getLocation()){
this.setDistanceToBase(this.getLocation().getX() + this.getLocation().getY());
}
else if(this.getDistanceToBase()<=0){
this.setDistanceToBase(0);
this.setLocation(new Address(0,0));
for (int i = 0; i < this.getPassengers().size(); i++) {
Citizen c = (Citizen)this.getPassengers().remove(i);
}
}
else{
this.setDistanceToBase(this.getDistanceToBase()-this.getStepsPerCycle());
}
}
}
I am an in-school amateur making a snake game in java, it is not complete and i have run into a problem that i cant seem to fix. the first and second parts of the body show up just fine after eating the target, but after that they do not.
code that adds a body part:
public void addBody(int x, int y) {
snekBody.add(new JPanel());
snekBody.get(snekBody.size() - 1).setBackground(new Color(new Random().nextInt(255), new Random().nextInt(255), new Random().nextInt(255)));
snekBody.get(snekBody.size() - 1).setVisible(true);
snekBody.get(snekBody.size() - 1).setBounds(x*score, y*score, BODY_WIDTH, BODY_HEIGHT);
game.add(snekBody.get(this.snekBody.size() - 1));
revalidate();
}
}
code that moves the body parts(moveUp, moveDown, etc.:
public synchronized void moveRight(int x, int y) {
timer++;
while (!this.right) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
head.setBounds(x, y, 20, 20);
xCoords.add(x);
yCoords.add(y);
//snekBody is an ArrayList of type JPanel
for(int i = 0; i < snekBody.size(); i++) {
if (i > 0) {
snekBody.get(i).setBounds(xCoords.get(timer-(10*score)), yCoords.get(timer-(10*score))+5, BODY_WIDTH, BODY_HEIGHT);
} else {
snekBody.get(i).setBounds(xCoords.get(timer-10), yCoords.get(timer-10)+5, BODY_WIDTH, BODY_HEIGHT);
}
}
repaint();
notifyAll();
revalidate();
}
code that calls addBody:
if (snek.up) {
snek.addBody(snek.xCoords.get(snek.timer-20), snek.yCoords.get(snek.timer-20));
the second picture is the snake when more than two targets have been eaten. the panels for the body just stop showing up.
The first picture is the snake when two targets have been eaten
Turns out that the panels were showing up on top of each other, thus why i could not see them.
I'm a math student writing a program to help with my research, but a small flaw is holding me up and I'm not sure what's going wrong.
In the first two calls to the power method, the computation is correct. In the loop, the first power works fine, but the matrix that is made when j=2 is a 2x2 matrix, instead of the correct one I usually get!
I'm sorry if I haven't included enough information, but the program is becoming quite large and I'm unfamiliar with conventions in CS and on SO. I appreciate any help.
public Queue<OrdInt> tree(Matrix inputMatr) {
Queue<OrdInt> holder = new LinkedList<OrdInt>();
LinkedList<Matrix> powers = new LinkedList<Matrix>();
powers.add(Matrix.identity(inputMatr.size));
int Np=0;
int j=1;
while(!powers.contains(inputMatr.power(j)) && j<Math.pow(2, inputMatr.size)){
powers.add(inputMatr.power(j));
try {
Np = (2*powers.get(j).nullspaceDim() - powers.get(j-1).nullspaceDim() - powers.get(j).matrixMultiply(inputMatr).nullspaceDim());
System.out.println("J+1 dim: " +powers.get(j).matrixMultiply(inputMatr).size);
} catch (Exception e) {
e.printStackTrace();
}
if(Np!=0){
holder.offer(new OrdInt(j, Np));
}
j++;
}
return holder;
}
edit: by request, the code for power and matrix multiply.
public Matrix matrixMultiply(Matrix one) throws Exception{
if(this.size != one.size){
throw new Exception("Incompatible Matrices.");
}
Matrix total = new Matrix(this.size);
for(int x=0; x<this.size; x++){
for (int y=0; y<this.size; y++){
int hold=0;
for(int z=0; z<this.size; z++){
hold += this.get(x,z)*one.get(z,y);
}
total.set(x,y,hold%2);
}
}
return total;
}
public Matrix power(int power) {
Matrix holder = this;
if(power==0){
return identity(this.size);
}
if(power==1){
return this;
}
else{
for(int x=0; x<power; x++){
try {
holder =holder.matrixMultiply(this);
} catch (Exception e) {
e.printStackTrace();
}
}
return holder;
}
}
I'm making a snake game(for those who don't know) where the snake is controlled by an AI using different algorithms to catch the food. The difference with the regular game is that the snake doesn't move unless a command has been sent by the AI.
My problem is that as soon as I run the AI, the AI creates a stack of commands to be executed to catch the food but my GUI just freezes; probably because it can't keep up with the amount of repaints that the move stacks cause. Through console logs, I can see that AI and the game logic is still running.
I tried to do Thread.sleep() after each move but I guess this just makes the entire program including the GUI sleep. I also have a Timer for my paintComponent but that doesn't seem to change anything.
How can you make your program sleep so that the GUI can catch up to what's happening?
EDIT:
Ok guys, I tried your solutions and it's still not working as it should. I don't really want to just dump the code here but I'm really lost. I have a timer that should repaint on a 140 millisecond interval(that's the value of DELAY), the commands are sent on a different thread which goes to sleep after each key press for 1000 milliseconds and I call repaint() after each call to move()... Here is relevant code(the original code without my modifications here):
private void initGame() {
dots = 5;
for (int z = 0; z < dots; z++) {
x[z] = 50 - z * 10;
y[z] = 50;
}
locateApple();
for (int k = blockNb - 1; k > 0; k--) {
locateBlock(k, apple_x, apple_y);
}
if (blocks) {
locateBlock(0, apple_x, apple_y);
}
timer = new Timer(DELAY, this);
timer.start();
startAi();
}
// AI CONTROLLER
public void startAi() {
Ai theAi = new Ai();
String move = "";
switch (ai) {
case "BFS":
move = theAi.bfs(this);
break;
}
//AI returns a string where each char is a move command
autoMove(move);
}
public void autoMove(String move) {
try {
Robot robot = new Robot();
System.out.println(move);
if (move != "#No") {
Thread thread = new Thread(new Runnable() {
public void run() {
for (int j = 0; j < move.length(); j++) {
if (move.charAt(j) == 'l') {
robot.keyPress(KeyEvent.VK_LEFT);
robot.keyRelease(KeyEvent.VK_LEFT);
}
if (move.charAt(j) == 'r') {
robot.keyPress(KeyEvent.VK_RIGHT);
robot.keyRelease(KeyEvent.VK_RIGHT);
}
if (move.charAt(j) == 'u') {
robot.keyPress(KeyEvent.VK_UP);
robot.keyRelease(KeyEvent.VK_UP);
}
if (move.charAt(j) == 'd') {
robot.keyPress(KeyEvent.VK_DOWN);
robot.keyRelease(KeyEvent.VK_DOWN);
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
thread.run();
}
} catch (AWTException e) {
e.printStackTrace();
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
private void doDrawing(Graphics g) {
if (inGame) {
g.drawImage(apple, apple_x, apple_y, this);
for (int j = 0; j < blockNb; j++) {
g.drawImage(block, block_x[j], block_y[j], this);
}
for (int z = 0; z < dots; z++) {
if (z == 0) {
g.drawImage(head, x[z], y[z], this);
} else {
g.drawImage(ball, x[z], y[z], this);
}
}
Toolkit.getDefaultToolkit().sync();
} else {
// gameOver(g);
}
}
private void move() {
for (int z = dots; z > 0; z--) {
x[z] = x[(z - 1)];
y[z] = y[(z - 1)];
}
if (leftDirection) {
x[0] -= DOT_SIZE;
}
if (rightDirection) {
x[0] += DOT_SIZE;
}
if (upDirection) {
y[0] -= DOT_SIZE;
}
if (downDirection) {
y[0] += DOT_SIZE;
}
}
#Override
public void actionPerformed(ActionEvent e) {
if (inGame) {
repaint();
}
}
private class TAdapter extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
leftDirection = true;
upDirection = false;
downDirection = false;
}
if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
rightDirection = true;
upDirection = false;
downDirection = false;
}
if ((key == KeyEvent.VK_UP) && (!downDirection)) {
upDirection = true;
rightDirection = false;
leftDirection = false;
}
if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
downDirection = true;
rightDirection = false;
leftDirection = false;
}
move();
checkApple();
checkCollision();
repaint();
}
}
EDIT 2: Also, I just wanted to point out that I tried to move without relying on a robot but to no avail.
Part 1:
Difference bettween Thread.sleep:
When you use it in main Thread(the Thread which java use to run the program)
then your whole program just freeze for that reason.
When you use A Thread for example(follow code)
new Thread(new Runnable(){
public void run(){
//do something...
while(flag==false)
Thread.sleep(a given time) //it need and try catch
else
//do your move
});
then only this Thread freeze (for a given time) or (Whatever you transform it to freeze).
In your case you can use a flag so every time a commant is hitten by user
the flag is going true and then again false to keep stopped the part of the
game you want but the main Thread your programms need to work still works
(if it is a window or anything...)
Part 2:(Basic form of your Thread)(The flag i use must be seen by all Methods)(public or private)
new Thread(new Runnable() {
public void run() {
flag=true;
while(flag==true){
if(move.equals("yes")){
//your code
move="no";
}else
Thread.sleep(20); //Sleep For a While(and then check again)
}
//That means that your Thread will run all over your game
//until game over (when game over just do the flag=false;)
//and The Thread will stop-exit
}});
*About Repaint Method(Dont call the repaint method too fast)
Call it only when the player make a move(this is the time that the frame
need to be repainted[Ok if you have .gif images in your game just dont see this]
Part 3:(When i made a similar game what i did)
Before some months i tried a similar game.The basic idea was a player who must past a labirinth so....
For each level i had one class like this...
public abstarct class Level2(){
//The game was into a panel like your.
//Here i added .setFocusable and .addKeyListener to panel
//Here it was an
public void actionListener(){
//The actionListener checked if the player found the door(for next level)
//Here it was the repaint so every time something happened repaint()
repaint();
}//End of Action Listener
//Use the paint or paintComponent what you need..
public void paint[or paintComponent](Graphics g){
//the 'squares' and the icons the had to be *repainted* again
}
//Here i had an extra class into this for the KeyListeners
//And I added the KeyListener like your game(up,down,left,right)
//I i said before i added this KeyListener to the panel
private class TAdapter extends KeyAdapter {
//KeyPressed,Released...etc
}
}
Thats the basic idea and for your game i think.
The Thread it's an extra option i can't help more you must find the way...
You should have a single "update" looped, from which your execute update commands and repaint request.
A simple approach would be to use a Swing Timer, which can trigger updates to a listener at regular intervals. It has the benefit of been triggered within the context of the EDT making it safe to update the UI from within. See How to use Swing Timers for more details
A more complex approach would be to use a Thread, which contained some kind of loop. This would perform the required updates and schedule repaint, but you'd need to insert Thread.sleep in to allow time for the updates to occur at a regular bases. The problem with this is you will need to synchronise your updates so that you don't update the model while painting is occurring as well synchronise you updates to the UI with the EDT
You need to have some sort of game scheduler loop and an understanding of how it works.
Here is some example code for java swing:
http://staticvoidgames.com/tutorials/swing/swingTimers
Another way to simplify things along with the scheduler is to make your game turn based at first. That is when the player moves 1turn (ie input) the game does all its processing and blocks on user input till the processing is done (ie single loop).
Every time your game AI outputs a new move, you need to call paint, but you also need to wait for whatever event is called when the painting is done before you output your next move, and you may want to wait like a second longer or something, play around with it
pseudo code
def fun 0 // entry point for program
// hook paint done event to func 1
call fun 2
def fun 1 // event handler method for when painting done
call fun 2
def fun 2 // function that does AI work
// do game logic
// call paint