我目前正致力于使用Java创建游戏,我想创建一个悬停效果。每当鼠标悬停在我在Gui中创建的矩形时,我想要将布尔值设置为true或false。我不确定我做错了什么。这是我的代码:
package com.tutorial.main;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import com.tutorial.main.Game.STATE;
public class Shop extends MouseAdapter{
private Game game;
private Handler handler;
private Random r = new Random();
private HUD hud;
private boolean enough_maxhealth = true;
private boolean enough_speed = true;
private boolean enough_frozen = true;
private boolean enough_blast = true;
private boolean health_info = false;
private boolean speed_info = false;
private boolean freeze_info = false;
private boolean blast_info = false;
//static to show other classes what is upgraded, can be implemented so it won't have to in future
public static int[] upgrades = {0,0,3,0};
private static int[] prices = {1,2,1,5};
//way program is built, coin has to be static
public static int COIN = 0;
private int shop_timer = 0;
//check if this is needed
private int timer_frozen_upgrade = 100;
public Shop(Game game, Handler handler, HUD hud){
this.game = game;
this.handler = handler;
this.hud = hud;
}
public void mousePressed(MouseEvent e){
int mx = e.getX();
int my = e.getY();
}
public void mouseReleased(MouseEvent e){
int mx = e.getX();
int my = e.getY();
//Shop buttons
if(game.gameState == STATE.Shop){
//back button
if(mouseOver(mx, my, 210, 350, 200, 64)){
game.gameState = STATE.Game;
return;
}
//health upgrade
if(mouseOver(mx, my, 80, 110, 150, 50)){
// Cost 1 coins for + 10 health
if (COIN >= prices[0]){
//checks if maxed, 3 is the max
if (upgrades[0] < 3){
//updates upgrades
upgrades[0] += 1;
//adds 10 health to players max health
HUD.MAX_HEALTH += 10;
COIN -= prices[0];
}
}else{
//set a message to be shown for 40 ticks
shop_timer = 40;
//signifies that you don't have enough
enough_maxhealth = false;
}
}
//back button
if(mouseOver(mx, my, 230, 380, 200, 64)){
game.gameState = STATE.Game;
}
//speed upgrade
if(mouseOver(mx, my, 80, 200, 150, 50)){
if(COIN >= prices[1]){
if(upgrades[1] < 3){
for(int i = 0; i < handler.object.size(); i++){
GameObject tempObject = handler.object.get(i);
if(tempObject.getId() == ID.Player){
//increases player default Vx and Vy by 108%
tempObject.setVx_Default(tempObject.getVx_Default() * 1.08f);
tempObject.setVy_Default(tempObject.getVy_Default() * 1.08f);
//costs 2 coins
COIN -= prices[1];
upgrades[1] += 1;
}
}
}
}else{
//set a message to be shown for 40 ticks
shop_timer = 40;
enough_speed = false;
}
}
//Freeze enemies
/*
if(mouseOver(mx, mx, Game.WIDTH - 230, 110, 150, 50)){
System.out.println("Pressed buy");
if(COIN >= 2){
if(upgrades[2] < 3){
upgrades[2] += 1;
System.out.println("Bought frozen");
}
}
}*/
//freeze
if(mouseOver(mx, my, Game.WIDTH - 230, 110, 150, 50)){
if(COIN >= prices[2]){
//if(upgrades[2] < 3){
for(int i = 0; i < handler.object.size(); i++){
GameObject tempObject = handler.object.get(i);
if(tempObject.getId() == ID.Player){
//increases player default Vx and Vy by 108%
COIN -= prices[2];
upgrades[2] += 1;
}
//}
}
}else{
//set a message to be shown for 40 ticks
shop_timer = 40;
enough_frozen = false;
}
}
//blast
if(mouseOver(mx, my, Game.WIDTH - 230, 200, 150, 50)){
if(COIN >= prices[3]){
if(upgrades[3] < 2){
for(int i = 0; i < handler.object.size(); i++){
GameObject tempObject = handler.object.get(i);
if(tempObject.getId() == ID.Player){
//increases player default Vx and Vy by 108%
COIN -= prices[3];
upgrades[3] += 1;
}
}
}
}else{
//set a message to be shown for 40 ticks
shop_timer = 40;
enough_blast = false;
}
}
}
}
//returns true or false depends of mouse is over certain cordinates
private boolean mouseOver(int mx, int my, int x, int y, int width, int height){
if(mx > x && mx < x + width){
if (my > y && my < y + height){
return true;
}else return false;
}else return false;
}
//checks if the mouse has entered one of the rectangles
public void mouseEntered(MouseEvent e){
int mx = e.getX();
int my = e.getY();
//Shop buttons
if(game.gameState == STATE.Shop){
//health box
if(mouseOver(mx, my, 80, 110, 150, 50)){
health_info = true;
}else{
health_info = false;
}
//speed box
if(mouseOver(mx, my, 80, 200, 150, 50)){
speed_info = true;
}else{
speed_info = false;
}
//freeze box
if(mouseOver(mx, my, 410, 110, 150, 50)){
freeze_info = true;
}
else freeze_info = false;
//blast box
if(mouseOver(mx, my, 410, 200, 150, 50)){
blast_info = true;
}else{
blast_info = false;
}
}
}
//checks if the mouse has exited one of the rectangles
public void mouseExited(MouseEvent e){
int mx = e.getX();
int my = e.getY();
//Shop buttons
if(game.gameState == STATE.Shop){
//health box
if(mouseOver(mx, my, 80, 110, 150, 50)){
health_info = false;
}else{
health_info = true;
}
//speed box
if(mouseOver(mx, my, 80, 200, 150, 50)){
speed_info = false;
}else{
speed_info = true;
}
//freeze box
if(mx > 110 && mx < 410){
if(my > 50 && my < 150){
freeze_info = false;
System.out.println("exit in");
}
else{
freeze_info = true;
System.out.println("exit left");
}
}
else{
freeze_info = true;
System.out.println("exit left");
}
//blast box
if(mouseOver(mx, my, 410, 200, 150, 50)){
blast_info = false;
}else{
blast_info = true;
}
}
}
public void tick(){
//reduces shop timer that shows message
if(shop_timer >= 0){
shop_timer--;
}
}
public void render(Graphics g){
//try to simplify/optimize
//Shop System
if(game.gameState == STATE.Shop){
//creates fonts for future reference
Font fnt = new Font("arial", 1, 50);
Font fnt2 = new Font("arial", 1, 20);
Font fnt3 = new Font("arial", 1, 17);
Font fnt4 = new Font("arial", 1, 11);
Font fnt5 = new Font("arial", 1, 9);
Font fnt6 = new Font("arial", 1, 40);
g.setColor(Color.black);
g.fillRect(0, 0, Game.WIDTH, Game.HEIGHT);
g.setColor(Color.gray);
g.setFont(fnt);
g.drawString("Shop", 250, 50);
//Displays Health
g.setColor(Color.gray);
g.fillRect(15, 15, 200, 32);
g.setColor(new Color(75, (int) HUD.greenValue, 0));
g.fillRect(15,15, (int) HUD.HEALTH * 2, 32);
g.setColor(Color.white);
g.drawRect(15, 15, 200, 32);
g.setFont(fnt2);
g.setColor(Color.white);
//Health upgrade
g.drawRect(80, 110, 150, 50);
g.drawString("Max Health", 90, 140);
g.setColor(Color.gray);
if(upgrades[0] >= 1){
g.setColor(Color.green);
}
g.fillRect(82, 170, 44, 14);
if(upgrades[0] >= 2){
g.setColor(Color.green);
}else{
g.setColor(Color.gray);
}
g.fillRect(134, 170, 44, 14);
if(upgrades[0] >= 3){
g.setColor(Color.green);
}else{
g.setColor(Color.gray);
}
g.fillRect(186, 170, 44, 14);
//Speed upgrade
g.setColor(Color.white);
g.drawRect(80, 200, 150, 50);
g.setColor(Color.gray);
if(upgrades[1] >= 1){
g.setColor(Color.green);
}
g.fillRect(82, 260, 44, 16);
if(upgrades[1] >= 2){
g.setColor(Color.green);
}else{
g.setColor(Color.gray);
}
g.fillRect(134, 260, 44, 16);
if(upgrades[1] >= 3){
g.setColor(Color.green);
}else{
g.setColor(Color.gray);
}
g.fillRect(186, 260, 44, 16);
g.setColor(Color.white);
g.setFont(fnt3);
g.drawString("Speed Upgrade", 82, 230);
//freeze enemy effect
g.drawRect(Game.WIDTH - 230, 110, 150, 50);
g.setColor(Color.white);
g.setFont(fnt3);
g.drawString("Freze Enemy", Game.WIDTH - 215, 140);
g.setFont(fnt4);
if(freeze_info){
g.drawString("Press 'f' to slow enemies", Game.WIDTH - 230, 173 );
g.drawString("(Can only be used once)", Game.WIDTH - 228, 185);
}
g.setFont(fnt6);
g.setColor(Color.red);
g.drawString("" + upgrades[2], 590, 150);
//blast for some odd ticks
g.setColor(Color.white);
g.drawRect(Game.WIDTH - 230, 200, 150, 50);
//g.setColor(Color.gray);
//g.fillRect(80, 210, 33, 10);
g.setFont(fnt2);
g.drawString("Blast", Game.WIDTH - 190, 230);
g.setFont(fnt4);
g.drawString("Press 'ctrl' for Imunity", Game.WIDTH - 230, 263 );
g.drawString("(Can only be used once)", Game.WIDTH - 228, 278);
g.setFont(fnt6);
g.setColor(Color.red);
g.drawString("" + upgrades[3], 590, 240);
g.setFont(fnt);
//back button
g.setColor(Color.white);
g.drawRect(230, 380, 200, 64);
g.drawString("Back", 260, 430);
if(!enough_maxhealth || !enough_speed || !enough_frozen || !enough_blast){
if(shop_timer > 0){
System.out.println(shop_timer);
g.setFont(fnt2);
g.setColor(Color.white);
if(!enough_maxhealth){
g.drawString("You need " + (prices[0] - COIN) + " coins more", 190, 90);
}else if(!enough_speed){
g.drawString("You need " + (prices[1] - COIN) + " coins more", 190, 90);
}else if(!enough_frozen){
g.drawString("You need " + (prices[2] - COIN) + " coins more", 190, 90);
}else if(!enough_blast){
g.drawString("You need " + (prices[3] - COIN) + " coins more", 190, 90);
}
}else{
enough_maxhealth = true;
enough_speed = true;
enough_frozen = true;
enough_blast = true;
}
}
}
}
}
我尝试用冻结来改变一些东西,看它是否会影响它的工作方式,但它仍然没有正常工作。每当我离开GUI时,MouseExit中的冻结布尔值都设置为true,但我不能使它对应于矩形。
答案 0 :(得分:0)
Rectangle2D类具有测试与其他矩形和/或单个点的碰撞的方法。
测试指定的坐标是否在边界内 形状
contains(double x, double y)
和
测试Shape的内部是否完全包含指定的内容 矩形区域。
contains(double x, double y, double w, double h)
我建议您重新构建代码以使用这些代码,如果您没有任何单元测试证明它有效,请写一些单元测试。
从此类扩展以继承对象的功能
********************编辑********************
class SomeObjectToRepresent extends Rectangle2D {
@override
public boolean contains(x, y){
boolean b = super.contains(x, y);
// change the state based on b
}
}
如上所述但不完全正确,只是想指出你正确的方向。
对于鼠标事件,我建议使用MouseMotionListener 相反,使用mouseMoved事件并检查组件,通过更新应用程序中的组件列表,根据鼠标是否在组件的边界内来设置其状态。组件管理器可以执行此操作,或者只要获得鼠标事件,您的JFrame就可以执行此操作。 这样做更野蛮,但它很容易实现,我怀疑你会有很多组件。 因为每次鼠标移动时,该列表将被更新或至少被触及。 我试图找出它的位置,但你可能需要两次添加鼠标监听器,一个用于运动,另一个用于原始。我知道这听起来很奇怪,但我依旧记得,当事件没有发生时,这对我来说也是一个问题。