1

私は自分で簡単なプロジェクトを作成しようとしています.このプロジェクトはテトリスのゲームのように機能します.長方形オブジェクトはタイマーで作成され、3つの異なる色でランダムに作成されます.オブジェクトはリストに保持されます. moveRectangle() と control() 関数で Y の配置を確認しました。同じ色が3つ並んでいる、またはブロックの上にある場合、それらは削除され、上のブロックがそれらを置き換えます。それが私の問題です。あらゆる方法を試しましたが、できませんでした。

これは、長方形オブジェクトを作成し、オブジェクトの x 座標と y 座標を制御するために機能します。

    package p1;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.Timer;

    public class DropObject {


    private  int yukseklik;
    private int block;
    private Color r;
    //private static int sayac=-1;
    private static int cntr;
    private Rectangle object;
    private static int sx=60;
    private static int [] sy=new int[9];
    public static int a=3;
    public static Color [] colorR=new Color[25];




    public DropObject(int yukseklik,int x,int y,int size,Color r)
    {   
    x=sx;
    //y=sy;
    this.r=EventRect.RColor();
    this.yukseklik=yukseklik;
    //set();
    this.object=new Rectangle(x,y,size,size);

    }

    /*public void set(){
        colorR[cntr]=this.r;
        //System.out.println("Renk: "+colorR[cntr]);
        cntr++;

    }*/


    public static int getSX(){
        return sx;
    }

    public static void setSX(int x){
        sx=x;
    }

    public static int getSY(){

        return sy[a];
    }

    public static void setSY(int y){
        sy[a]=y;

    }

    public Color getColor(){
        //colorR[++sayac]=this.r;
        return this.r;
    }

    public  int getYukseklik(){
        return yukseklik;
    }
    public void setYukseklik(int yukseklik){
        this.yukseklik=yukseklik;

    }
    public Rectangle getObject(){
        return object;
    }
    public void setObject(Rectangle object){
        this.object=object;
        this.object.x=sx;
    }

         }

EventRect クラスは、オブジェクトの動きを提供し、オブジェクトの y 座標位置を指定します。

package p1;


import java.awt.Button;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D; 
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
//import java.util.Timer;
import java.util.TimerTask;

import javax.swing.Timer;

import java.util.Random;

import javax.swing.JPanel;

public class EventRect extends JPanel {

private static int yukseklik=340;
private static Color BlockC;
private DropObject koordinat;
private int zheight=yukseklik;
private int fheight=yukseklik;
private int sheight=yukseklik;
private int theight=yukseklik;
private int foheight=yukseklik;
private int fiheight=yukseklik;
private int ssheight=yukseklik;
private int seheight=yukseklik;
private int seiheight=yukseklik;
private int counter=-1;
private int counter1=-1;
private int counter0=-1;





private List<DropObject> objects=new LinkedList<DropObject>();
private LinkedList<TimerTask> tasklist=new LinkedList<TimerTask>();
Timer timet;
int i=1;

public EventRect(){
addKeyListener(new InputKey());
setFocusable(true);
//System.out.println((objects.size()));
koordinat=new DropObject(yukseklik,60,-20,20,BlockC);
objects.add(koordinat); 
startSampling();
//timet=new Timer(10,this);
//timet.start();
}




@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d=(Graphics2D)g;
for(DropObject o : objects){
    Rectangle r=o.getObject();
    g2d.setColor(o.getColor());
    //System.out.println(r.x);
    g2d.fillRect(r.x, r.y, r.width+1, r.height+1);
   // System.out.println(objects.size());
}


}

public void moveRectangle(){
for(int i=(objects.size()-1);i>=(objects.size()-1);i--){
    DropObject o=objects.get(i);
    Rectangle r=o.getObject();
    if(DropObject.a==0){

       DropObject.setSY(zheight);
           o.setYukseklik(DropObject.getSY());

      }
    if(DropObject.a==1){

       DropObject.setSY(fheight);
           o.setYukseklik(DropObject.getSY());


      }
    if(DropObject.a==2){

       DropObject.setSY(sheight);
           o.setYukseklik(DropObject.getSY());


      }
    if(DropObject.a==3){
           DropObject.setSY(theight);
           o.setYukseklik(DropObject.getSY());


           }


    if(DropObject.a==4){

       DropObject.setSY(foheight);
           o.setYukseklik(DropObject.getSY());

      }
    if(DropObject.a==5){

       DropObject.setSY(fiheight);
           o.setYukseklik(DropObject.getSY());


      }
    if(DropObject.a==6){

           DropObject.setSY(ssheight);
           o.setYukseklik(DropObject.getSY());

      }
    if(DropObject.a==7){

       DropObject.setSY(seheight);
           o.setYukseklik(DropObject.getSY());

      }
    if(DropObject.a==8){

       DropObject.setSY(seiheight);
           o.setYukseklik(DropObject.getSY());

      }



    if(o.getYukseklik()>=0){
        if(r.y<o.getYukseklik()){
            r.y+=r.height;
            o.setObject(r); 

        }else{
            o.setYukseklik(o.getYukseklik()-r.height);

        }

    }

    if(r.y == o.getYukseklik()){
         control();

         objects.add(new DropObject(o.getYukseklik(),60,-20,20,BlockC));


    }   
}
}


void control(){
    if(DropObject.a==0){
           zheight-=20;
           DropObject.setSY(zheight);

      }
     if(DropObject.a==1){
           fheight-=20;
           DropObject.setSY(fheight);

      }

     if(DropObject.a==2){
           sheight-=20;
           DropObject.setSY(sheight);

      }


      if(DropObject.a==3){

           theight-=20;
           DropObject.setSY(theight);

      }

      if(DropObject.a==4){
            foheight-=20;
            DropObject.setSY(foheight);

        }
      if(DropObject.a==5){
            fiheight-=20;
            DropObject.setSY(fiheight);

        }
      if(DropObject.a==6){
            ssheight-=20;
            DropObject.setSY(ssheight);

        }
      if(DropObject.a==7){
            seheight-=20;
            DropObject.setSY(seheight);

        }
      if(DropObject.a==8){
            seiheight-=20;
            DropObject.setSY(seiheight);

      }


    }



void startSampling(){
TimerTask task=new TimerTask(){
    public void run(){
        moveRectangle();
        repaint();


    }
};
java.util.Timer timer=new java.util.Timer();
timer.scheduleAtFixedRate(task,0,150);
tasklist.add(task);

}

void stopSampling(){
if(tasklist.isEmpty()){
    return;
}
tasklist.removeFirst().cancel();
}

public static Color RColor(){
Color [] Array={Color.blue,Color.pink,Color.gray};
Random random=new Random();
BlockC=Array[random.nextInt(Array.length)];
 return BlockC;
}
}

鍵盤の動き;

   package p1;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class InputKey extends KeyAdapter{

    public void keyPressed(KeyEvent e){
        int keys=e.getKeyCode();
        if(keys==KeyEvent.VK_RIGHT){
            //System.out.println("saga kaydi");
            if(DropObject.getSX()<160)
            DropObject.setSX(DropObject.getSX()+20);
            if(DropObject.a<8){
            DropObject.a++;
            System.out.println("a nin degeri: "+DropObject.a);
            }

        }
        else if(keys==KeyEvent.VK_LEFT){
            if(DropObject.getSX()>0)

            DropObject.setSX(DropObject.getSX()-20);
            if(DropObject.a>0){
                DropObject.a--;

                }


        }
    }

}



package p1;

import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Main implements Runnable{

@Override 
public void run(){

JFrame frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container container=frame.getContentPane();
container.setLayout(new GridLayout(0,1));
container.add(new EventRect());

frame.setSize(197,400);
frame.setVisible(true);
//container.setBackground(Color.BLUE);


}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Main());

}

}
4

2 に答える 2

0

これは、元のコードとアイデアに基づいて大幅に変更されたソリューションです。ブロックを追跡するためのオブジェクト指向アプローチを実装しています。ブロックのリストを使用して各列を表します。また、描画のためにループできるように、画面上のすべてのブロックへの参照を格納するための ArrayList もあります。申し訳ありませんが、あなたの母国語ではありませんが、それでも理解できることを願っています. 必要なメイン コードは、ブロックの隣接検出と削除を処理する BlockBuster クラスに格納されます。各クラスを独自のファイルに分離する必要があります。

Block.java

package p1;

import java.awt.Color;
import java.awt.Rectangle;
import java.util.Random;

public class Block {

    /**
     * Color
     */
    private Color color;
    /**
     * The pixel coordinate bounding rectangle for the block.
     */
    private Rectangle bounds;
    /**
     * the integer column
     */
    private int column;

    /**
     * Creates a new instance of a block at the specified
     * 
     * @param y Distance in pixels from the top of the form.
     * @param column The integer column index (0-8)
     * @param size The integer size.
     */
    public Block(int y, int column, int size) {
        this.color = RandomColor();
        this.bounds = new Rectangle(20*column, y, size, size);
        this.column = column;
    }

    /**
     * Gets the color of this block.
     * @return the color of this block.
     */
    public Color getColor() {
        return this.color;
    }

    /**
     * Gets the pixel bounds for this block.
     * @return The bounds.
     */
    public Rectangle getBounds() {
        return bounds;
    }

    /**
     * Sets the bounds for this block.
     * @param object 
     */
    public void setBounds(Rectangle object) {
        this.bounds = object;
    }

    /**
     * This is Elevation in units of blocks, like column 
     * @return 
     */
    public int getLevel(){
        return (340 - this.getBounds().y)/20;
    }

    /**
     * Gets the bottom of the block.
     * @return 
     */
    public int getBottom(){
        return this.bounds.y + this.bounds.height;
    }

    /**
     * Gets the integer column index of the block (0-8)
     * @return the column
     */
    public int getColumn() {
        return column;
    }

    /**
     * Sets the integer column index of the block (0-8)
     * @param column the column to set
     */
    public void setColumn(int column) {
        this.column = column;
    }

    /**
     * Generates a random color.
     * @return Color
     */
    public static Color RandomColor() {
        Color[] Array = {Color.blue, Color.pink, Color.gray};
        Random random = new Random();
        return Array[random.nextInt(Array.length)];
    }
}

BlockBuster.java

package p1;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

/**
 * This class handles the work of finding adjacent blocks.
 * To delete blocks ONLY if the blocks are horizontally adjacent,
 * then you can remove the "Up" and "Down" sections.
 * @author Ted
 */
public class BlockBuster {

    private List<Block> queue;
    private List<Block> bustList;

    /**
     * Creates a new instance of the BlockBuster class.
     */
    public BlockBuster() {
        queue = new ArrayList<Block>();
    }

    /**
     * This method busts the blocks of with matching colors
     */
    public void bustBlocks() {
        Block block = BlockManager.getInstance().getFallingBlock();
        bustList = new ArrayList<Block>();
        queue.add(block);
        while (queue.size() > 0) {
           Block current = queue.get(0);
           addMatchingNeighbors(current);
           queue.remove(0);
           if(!bustList.contains(current)){
                bustList.add(current);
           }

        }
        if(bustList.size() > 2){
          for(Block busted : bustList){
              BlockManager.getInstance().RemoveBlock(busted);
              List<Block> check = BlockManager.getInstance().getAllBlocks();
              if(check.contains(busted)){
                boolean stop = true;
              }
          }
        }
    }

    /**
     * This method adds neighbors that match in color to the queue
     * as long as they don't already exist in the queue or bustlist.
     * @param block The current block to consider.
     */
    private void addMatchingNeighbors(Block block) {
        // currently only check by 4 connectivity
        int x = block.getColumn();
        int y = block.getLevel();
        Color color = block.getColor();

        // left
        Block leftBlock = getBlock(x - 1, y);
        if(colorMatches(color, leftBlock)){
             queue.add(leftBlock);
        }
        // Right
        Block rightBlock = getBlock(x + 1, y);
        if(colorMatches(color, rightBlock)){
            queue.add(rightBlock);

        }
        // Up
        Block upBlock = getBlock(x, y + 1);
        if(colorMatches(color, upBlock)){
            queue.add(upBlock);

        }

        Block downBlock = getBlock(x, y-1);
        if(colorMatches(color, downBlock)){
            queue.add(downBlock);
        }

    }

    /**
     * This tests whether the block's color matches the specified
     * color, and whether or not the block is already in a list.
     * @param color The color that should match for deletion.
     * @param block The block to be removed.
     * @return 
     */
    public boolean colorMatches(Color color, Block block){
       if(block == null){
           return false;
       }
       if(bustList.contains(block)){
           return false;
       }
       if(queue.contains(block)){
           return false;
       }
       return (block.getColor().equals(color));
    }

    /**
     * This finds a block at the specified column and height.
     * @param column The integer column index (0-8)
     * @param height The integer level (in blocks)
     * @return a Block
     */
    public Block getBlock(int column, int level) {

        Column[] columns = BlockManager.getInstance().getColumns();
        if (column >= 0 && column < 10) {
            if (columns[column].getBlocks().size() > level && level >= 0) {
                Block result = columns[column].getBlocks().get(level);
                if(bustList.contains(result)){
                    return null;
                }
                return result;
            }
        }
        return null;
    }
}

BlockManager.java

package p1;

import java.util.ArrayList;
import java.util.List;

/**
 * This is a singleton to control the blocks and is visible
 * from the other classes in the application.
 * @author Ted
 */
public class BlockManager {

    /**
     * The single instance of a falling block.
     */
    private Block fallingBlock;

    /**
     * All blocks on the page, including the falling one.
     */
    private List<Block> allBlocks;

    /**
     * The array of columns at the bottom, containing blocks.
     */
    private Column[] columns;

    /**
     * Creates an instance of a BlockManager class.  As part
     * of the singleton pattern, this is private so that
     * you can only access the shared instance.
     */
    private BlockManager() {
        allBlocks = new ArrayList<Block>();
        columns = new Column[9];
        for(int i = 0; i < 9; i++)
        {
            columns[i] = new Column();
        }
    }

    /**
     * Gets the single shared instance of the singleton.
     * @return BlockManager
     */
    public static BlockManager getInstance() {
        return BlockManagerHolder.INSTANCE;
    }
    private static class BlockManagerHolder {
        private static final BlockManager INSTANCE = new BlockManager();
    }

    /**
     * Adds a new falling block to the top of the control.
     */
    public void AddBlock(){
        fallingBlock = new Block(0, 3, 20);
        allBlocks.add(fallingBlock);
    }

    /**
     * Removes the specified block.
     * @param block 
     */
    public void RemoveBlock(Block block){
        allBlocks.remove(block);
        List<Block> blocks = columns[block.getColumn()].getBlocks();
        if(blocks.size() > block.getLevel()){
           for(int i = block.getLevel(); i < blocks.size(); i++)
           {
               // Make blocks above this block drop.
               blocks.get(i).getBounds().y += 20;

           }
        }
        columns[block.getColumn()].getBlocks().remove(block);
    }



    /**
     * Gets the falling block.
     * @return the fallingBlock
     */
    public Block getFallingBlock() {
        return fallingBlock;
    }

    /**
     * Sets the falling block.
     * @param fallingBlock the fallingBlock to set
     */
    public void setFallingBlock(Block fallingBlock) {
        this.fallingBlock = fallingBlock;
    }

    /**
     * Gets the list of all blocks visible on the form,
     * including the falling block.
     * @return the allBlocks
     */
    public List<Block> getAllBlocks() {
        return allBlocks;
    }

    /**
     * Sets the list of all blocks visible on the form,
     * including the falling block.
     * @param allBlocks the allBlocks to set
     */
    public void setAllBlocks(List<Block> allBlocks) {
        this.allBlocks = allBlocks;
    }

    /**
     * Gets the array of columns containing blocks at the bottom.
     * @return the columns
     */
    public Column[] getColumns() {
        return columns;
    }

    /**
     * Sets the array of columns containing blocks at the bottom.
     * @param columns the columns to set
     */
    public void setColumns(Column[] columns) {
        this.columns = columns;
    }


}

列.java

package p1;

import java.util.ArrayList;
import java.util.List;

/**
 * A Column is an object that contains a list of the blocks stored
 * in a vertical stack at the bottom of the game.  Each block object
 * points to the same object instance in allBlocks.
 * @author Ted
 */
public class Column {
    private static int maxHeight = 340;
    private List<Block> blocks;

    /**
     * Gets the maximum vertical pixel height of the form.
     * @return the maxHeight
     */
    public static int getMaxHeight() {
        return maxHeight;
    }

    /**
     * Sets the maximum vertical pixel height of the form.
     * @param aMaxHeight the maxHeight to set
     */
    public static void setMaxHeight(int aMaxHeight) {
        maxHeight = aMaxHeight;
    }


    /**
     * Creates a new instance of the column class.
     */
    public Column(){
        blocks = new ArrayList<Block>();
    }

    /**
     * Gets the amount of space remaining in this column
     * @return 
     */
    public int getDepthRemaining(){
        return maxHeight - getBlockHeight();
    }

    /**
     * Gets the total height of all the blocks in this column
     * @return 
     */
    public int getBlockHeight(){
        int height = 0;
        for(Block block : blocks){
            height += block.getBounds().height;
        }
        return height;
    }

    /**
     * Gets the list of blocks associated with this column.
     * The 0 index is at the bottom.
     * @return the dropObjects
     */
    public List<Block> getBlocks() {
        return blocks;
    }

    /**
     * Sets the list of blocks associated with this column.
     * @param dropObjects the dropObjects to set
     */
    public void setBlocks(List<Block> dropObjects) {
        this.blocks = dropObjects;
    }
}

EventRect.java

package p1;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.LinkedList;
import java.util.TimerTask;
import javax.swing.Timer;
import javax.swing.JPanel;

/**
 * EventRect is the main form for the game.
 */
public class EventRect extends JPanel {
    /**
     * @return the fallingBlock
     */
    public static Block getFallingBlock() {
        return BlockManager.getInstance().getFallingBlock();
    }

    private BlockBuster blockBuster;
    private LinkedList<TimerTask> tasklist = new LinkedList<TimerTask>();
    Timer timet;
    int i = 1;

    /**
     * Creates a new instance of the main form for the project.
     */
    public EventRect() {
        BlockManager.getInstance().AddBlock();
        this.blockBuster = new BlockBuster();
        addKeyListener(new InputKey());
        setFocusable(true);
        startSampling();
    }

    /**
     * Paints all the blocks onto the screen, including the falling block.
     * @param g The Graphics surface of the form.
     */
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        for (Block dropObject : BlockManager.getInstance().getAllBlocks()) {
            Rectangle bounds = dropObject.getBounds();
            g2d.setColor(dropObject.getColor());
            g2d.fillRect(bounds.x, bounds.y, bounds.width + 1, bounds.height + 1);
        }
    }

    /**
     * This handles the downward motion of the falling block.
     */
    public void moveRectangle() {
        Column[] columns = BlockManager.getInstance().getColumns();
        if(getFallingBlock().getBounds().getY() >= 
          columns[getFallingBlock().getColumn()].getDepthRemaining()){
            // We hit the top of the column, so add this block to the column
            columns[getFallingBlock().getColumn()].getBlocks().add(getFallingBlock());
            blockBuster.bustBlocks();
            BlockManager.getInstance().AddBlock();
        }
        else{
            BlockManager.getInstance().getFallingBlock().getBounds().y += 20;
        }
    }

    /**
     * This method was made final because it is called from the
     * constructor.  This starts game timers (from original post).
     */
    final void startSampling() {
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                moveRectangle();
                repaint();
            }
        };
        java.util.Timer timer = new java.util.Timer();
        timer.scheduleAtFixedRate(task, 0, 150);
        tasklist.add(task);
    }

    /**
     * This method removes the timer from the tasklist.
     */
    void stopSampling() {
        if (tasklist.isEmpty()) {
            return;
        }
        tasklist.removeFirst().cancel();
    }


}

入力キー.java

package p1;

import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

/**
 * This class handles the movement of blocks.  This 
 * class was modified to include collision detection
 * with blocks in a neighboring column.
 */
public class InputKey extends KeyAdapter {

    @Override
    public void keyPressed(KeyEvent e) {
        int keys = e.getKeyCode();
        Block block = EventRect.getFallingBlock();
        if (block == null) {
            return;
        }
        Rectangle rect = block.getBounds();
        if (keys == KeyEvent.VK_RIGHT) {
            //Check for right bounds
            if (rect.x < 160) {
                // Check to see if we run into another block
                int level = block.getLevel();
                int column = block.getColumn();
                if (BlockManager.getInstance().getColumns()[column + 1].getBlocks().size() > level) {
                    // we ran into a block
                    return;
                }
                rect.x += 20;
                block.setColumn(rect.x / 20);
            }
        } else if (keys == KeyEvent.VK_LEFT) {
            // Check for left bounds
            if (rect.x > 0) {
                // Check to see if we run into another block
                int level = block.getLevel();
                int column = block.getColumn();
                if (BlockManager.getInstance().getColumns()[column + 1].getBlocks().size() > level) {
                    // we ran into a block
                    return;
                }
                rect.x -= 20;
                block.setColumn(rect.x / 20);
            }
        }
    }
}

Main.java

package p1;

import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

/**
 * This class runs the program.
 * @author Ted
 */
public class Main implements Runnable {

    @Override
    public void run() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container container = frame.getContentPane();
        container.setLayout(new GridLayout(0, 1));
        container.add(new EventRect());
        frame.setSize(197, 400);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Main());
    }
}
于 2013-07-20T12:47:54.573 に答える
0

私はかつてゲームのようなテトリスを実装していましたが、衝突を検出して領域を塗りつぶす方法は、データ構造に従うことでした

  1. 形状が落ち着く空間全体は、配列で表されるグリッドであり、最初は 0 で、ブロックが落ちるセルでは 1 で埋められます。
  2. すべてのブロックは、必要に応じて 1 で埋めることによって形状が定義された正方形のグリッドでもあります。

このモデルの後、衝突と塗りつぶされた領域を検出するのは簡単です。色を別の方法で処理したい場合は、セルのすべての色に 1,2,3.. などを割り当てることができます。それが役立つことを願っています。

于 2013-07-20T03:35:18.580 に答える