7月13暑期培训

本文详细解读了Java AWT中Game2048游戏面板的修改,包括Graphics.fillRoundRect方法、游戏状态切换、瓷砖渲染与移动逻辑。通过关键方法如startGame、drawGrid和move函数,展示了游戏界面的绘制与用户交互过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对昨天的程序进行修改:

void java.awt.Graphics.fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)

Parameters:

x the x coordinate of the rectangle to be filled.

y the y coordinate of the rectangle to be filled.

width the width of the rectangle to be filled.

height the height of the rectangle to be filled.

arcWidth the horizontal diameter of the arc at the four corners.

arcHeight the vertical diameter of the arc at the four corners.

package game2048;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

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

public class Game2048 extends JPanel 
{

    /**
     * 2048游戏
     */
    private static final long serialVersionUID = 1L;
    enum State //1.四种状态
    {
        start,win,running,over
    }
    final Color[] colorTable= 
    {
        new Color(0x701710), new Color(0xFFE4C3), new Color(0xfff4d3),
        new Color(0xffdac3), new Color(0xe7b08e), new Color(0xe7bf8e),
        new Color(0xffc4c3), new Color(0xE7948e), new Color(0xbe7e56),
        new Color(0xbe5e56), new Color(0x9c3931), new Color(0x701710)
     };
    final static int target=2048;
    static int highest,score;
    private Color gridColor= new Color(0xbbada0);//整体颜色
    private Color emptyColor= new Color(0xcdc1b4);
    private Color startColor= new Color(0xfffbcd);
    private Random random=new Random();
    private Tile[][] tiles;
    private int side=4;
    private State gamestate=State.start ;
    private boolean checkingAvailableMoves;
    
    public Game2048() //2.构造方法
    {
        setPreferredSize(new Dimension(900, 700));
        setBackground(new Color(0xfaf8ef));
        setFont(new Font("SansSerif",Font.BOLD,48));
        setFocusable(true);
        addMouseListener(new MouseAdapter() 
        {
            public void mousePressed(MouseEvent e) {
            startGame();
            repaint();
            }
        });
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                switch (e.getKeyCode()) 
                {
                case KeyEvent.VK_UP:
                    moveUp();
                    break;
                case KeyEvent.VK_DOWN:
                    moveDown();
                    break;
                case KeyEvent.VK_LEFT:
                    moveLeft();
                    break;
                case KeyEvent.VK_RIGHT:
                    moveRight();
                    break;
                }    
                repaint();
            }                
        });
    }
    
    @Override
    protected void paintComponent(Graphics gg) //3.渲染
    {
        super.paintComponent(gg);
        Graphics2D g =(Graphics2D)gg;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        drawGrid(g);//画表格
    }
     void startGame() //开始游戏
        {
            if (gamestate != State.running) 
            {
                score=0;
                highest=0;
                gamestate=State.running;
                tiles=new Tile[side][side];
                addRandomTile();//产生一个2
                addRandomTile();//产生一个2        
            }
            
        }

     void drawGrid(Graphics2D g) //4.游戏状态,出现游戏相应界面
     {
        g.setColor(gridColor);        
        g.fillRoundRect(200, 100, 499,499,15,15);//整个表格的大小499*499
        if (gamestate == State.running)//开始后的状态,里面有两个随机数
        {
         for(int r = 0; r < side; r++)//循环,找到随机数的位置
             for(int c = 0; c < side; c++)
                 if (tiles[r][c]==null)
                 {
                     g.setColor(emptyColor);
                     g.fillRoundRect(215+c*121,115+r*121,106 ,106, 7,7);//空格子大小为106*106
                 }
                 else drawTile(g,r,c);//找到随机数的位置,创建随机数格子及颜色
        }
        else //开始前的游戏界面、结束后游戏界面
        {
        g.setColor(startColor);    //开始界面颜色
        g.fillRoundRect(215, 115, 469, 469, 7, 7);//开始界面的大小 469*469,与原来画面499*499叠加,会形成一种边框的错觉
        g.setColor(gridColor.darker());//设置游戏界面字体颜色"2048",.darker()会加深原来的颜色    
        //g.setColor(gridColor); //与上面颜色的区别就是“浅”
        g.setFont(new Font("SansSerif",Font.BOLD,128));
        g.drawString("2048", 310, 270);
        g.setFont(new Font("SansSerif",Font.BOLD,20));
        if (gamestate==State.win) g.drawString("Sucess!", 390, 350);
        else if (gamestate==State.over) g.drawString("game over", 400, 350);
        g.setColor(gridColor);    
        g.drawString("restart", 400, 350);
        g.drawString("use arrow keys to move tiles", 400, 350);
        }
        
     }

    private void drawTile(Graphics2D g, int r, int c)//5.根据上面找到的随机数位置,渲染随机数格子
    {
        int value=tiles[r][c].getValue();//读取当前格子的值,判断是否可以合并
        g.setColor(colorTable[(int)(Math.log(value )/Math .log(2))+1]);//设置颜色
        g.fillRoundRect(215+c*121,115+r*121,106,106,7,7);//106*106大小
        String string=String.valueOf(value);
        g.setColor(value<128?colorTable[0]:colorTable[1]);
        FontMetrics fm = g.getFontMetrics();
        int asc=fm.getAscent();
        int dec=fm.getDescent();
        int x=215+c*121+(106-fm.stringWidth(string))/2;
        int y=115+r*121+(asc+(106-(asc+dec))/2);
       g.drawString(string, x, y);
    }
    private void addRandomTile() //6.放东西
    {
        int pos=random.nextInt(side*side);
        int row,col;
        do {
            pos=(pos+1)%(side*side);
            row=pos/side;
            col=pos%side;                    
        } while (tiles[row][col]!=null);
        int val=random.nextInt(10)==0?4:2;
        tiles[row][col]=new Tile(val);//只要一移动就添加一个
    }
    private boolean move(int countDownFrom,int yIncr,int xIncr)//7.控制键盘的移动键动作
    {
        boolean moved =false;
        for(int i=0;i<side*side;i++)
        {
            int j=Math.abs(countDownFrom-i);
            int r=j/side;
            int c=j%side;
            if (tiles[r][c]==null) continue;
            int nextR=r+yIncr;
            int nextC=c+xIncr;
            while (nextR >= 0 && nextR < side && nextC >= 0 && nextC < side)
            {
                Tile next=tiles[nextR][nextC];//合并后
                Tile curr=tiles[r][c];//合并前
                if (next==null)
                {
                    if (checkingAvailableMoves) 
                        return true;
                    tiles[nextR][nextC]=curr;
                    tiles[r][c]=null;
                    r=nextR;//新的值
                    c=nextC;
                    nextR+=yIncr;
                    nextC+=xIncr;
                    moved=true;
                }
                else if (next.canMergeWith(curr)) 
                {
                    if (checkingAvailableMoves) 
                        return true;
                    int value=next.mergeWith(curr);
                    if (value>highest) 
                        highest=value;
                    score+=value ;
                    tiles[r][c]=null;
                    moved=true;
                    break;
                }else
                    break;
                
            }
            
        }
         if (moved) {
                if (highest < target) {
                    clearMerged();
                    addRandomTile();
                    if (!movesAvailable()) {
                        gamestate = State.over;
                    }
                } else if (highest == target)
                    gamestate = State.win;
            }
            return moved;
    }
    boolean moveRight() 
    {
        return move(side*side-1,0,1);        
    }
    boolean moveLeft() 
    {
        return move(0,0,-1);        
    }

    boolean moveDown() 
    {
        return move(side*side-1,1,0);        
    }

    boolean moveUp() 
    {
        return move(0,-1,0);        
    }
    void clearMerged()
    {
        for(Tile[] row:tiles)
            for(Tile tile:row)
                if(tile!=null) tile.setMerged(false);
    }
   boolean movesAvailable() 
   {
       checkingAvailableMoves=true;
       boolean hasMoves= moveUp() || moveDown() || moveLeft() || moveRight();
       checkingAvailableMoves=false;
       return hasMoves;
   }
    

    public static void main(String[] args) //入口
    {
        SwingUtilities.invokeLater(()->{
            JFrame f =new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setTitle("2048");
            f.setResizable(true);
            f.add(new Game2048(),BorderLayout.CENTER);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        });
        

    }
    

}
class Tile  //在随机数时被使用,看能不能被合并
{
    private boolean merged;
    private  int value;
    Tile(int val) 
    {
     value=val;
    }
    int getValue()
    {
    return    value;
    }
    void setMerged(boolean m) 
    {
        merged = m;
    }
        
    boolean canMergeWith(Tile other)
    {
        return !merged && other != null && !other.merged && value == other.getValue();
    }
    
    
    int mergeWith(Tile other)
    {
        if (canMergeWith(other))
        {
            value*=2;
            merged=true;
            return value;
        }
        return -1;
    }
}
 

教育培训行业的话务员培训话术主要是为了帮助潜在客户了解教育课程和服务,并引导他们完成报名流程。以下是几个关键点: 1. **开场白**:首先要有礼貌地自我介绍并确认对方身份。“您好,这里是XX教育机构,我是客服代表小李。请问您是张三先生/女士吗?”这样的问候可以拉近与客户的距离。 2. **需求挖掘**:“我们了解到您最近对我们的编程培训班感兴趣,请问您可以跟我详细说一下您的学习目标以及期望通过这次培训达到什么样的效果呢?”这有助于理解客户需求以便提供定制化建议。 3. **产品介绍**:根据收集到的信息向用户推荐合适的课程。“基于您提到的目标,我认为我们的Python基础班非常适合初学者入门计算机科学领域。”同时强调该课程的优势如师资力量、教学资源等。 4. **解决疑虑**:针对客户提出的疑问给出专业解答。“关于费用方面的问题,我们有多种支付方案供选择;另外我们也设有试听课程让学员能够提前体验课堂氛围。” 5. **促单技巧**:适时给予优惠信息鼓励快速决策。“目前正值暑期促销期间,在8月底之前报名还可以享受八折优惠哦!” 6. **后续跟进**:无论是否立即成交都要保持友好态度,并告知接下来将采取哪些步骤。“如果您有任何其他问题随时欢迎联系我们,我们会继续关注您的进度直到顺利完成注册为止。” 7. **结束语**:最后感谢对方的时间并且期待再次交流的机会。“非常感谢今天能有机会跟您聊聊这个话题,希望很快能在课堂上见到您!”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值