明明只建立了一个线程类,为何进行时这么卡,而且没有转头效果

问题描述

明明只建立了一个线程类,为何进行时这么卡,而且没有转头效果

这是GameUtil里的

 public static void addFishes(ArrayList<Fish> Fishes){
        int count=rand.nextInt(6)+5;
        for(int i=0;i<count;i++){
            Fish f=new Fish();
            f.setState(State_Swin);
            f.setLevel(rand.nextInt(11)+1);
            f.setDrawCount(15);
            BufferedImage image=null;
            BufferedImage[] img=new BufferedImage[f.getDrawCount()];
            for(int j=1;j<f.getDrawCount();j++){
                String path="image/"+f.getLevel()+"/"
            +f.getState()+"/"+f.getState()+"_cycle."+j+".png";
                try {
                    image=ImageIO.read(new FileInputStream(path));
                    img[j-1]=image;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            f.setImage(img);
            f.setDrawIndex(0);
            int x=rand.nextInt(800)-f.getWidth();
            int y=rand.nextInt(480)-f.getHeight();
            f.setPoint(new Point(x,y));
            x=rand.nextInt(800)-f.getWidth();
            y=rand.nextInt(480)-f.getHeight();
            f.setTarget(new Point(x,y));
            f.setDirection(GameUtil.getDirectionByPoint(f.getPoint(), f.getTarget()));
            Fishes.add(f);
        }
    }

这是GameJPanel的DrawThread类

 class DrawThread extends Thread{
        public void run(){
            while(true){
                 for(Fish f :fishes){
                     int nowDrawIndex=f.getDrawIndex()+1;
                     if(nowDrawIndex==f.getDrawCount()){
                         if(f.getState().equals(GameUtil.State_Eat))
                             f.setState(GameUtil.State_Swin);
                         if(f.getState().equals(GameUtil.State_Turn))
                             f.setState(GameUtil.State_Swin);
                         nowDrawIndex=0;
                     }
                     f.setDrawIndex(nowDrawIndex);
                    //还需改变每条鱼的point
                        //f.setPoint(new Point(f.getPoint().x,f.getPoint().y-10));
                        //游动到目的地,x,y分别需要移动的距离
                        int dx = f.getTarget().x-f.getPoint().x;
                        int dy = f.getTarget().y-f.getPoint().y;
                        //真实距离
                        double d = Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2));
                        //x,y 相对d 的比率
                        double rateX = dx/d;
                        double rateY = dy/d;
                        //每0.1秒在x,与y轴移动的距离=比率*速度
                        int sx = (int)(rateX * GameUtil.FISH_SPEED);
                        int sy = (int)(rateY * GameUtil.FISH_SPEED);
                        //获取移动后鱼的坐标
                        int newX = f.getPoint().x+sx;
                        int newY = f.getPoint().y+sy;
                        if(Math.abs(f.getTarget().x-newX)<=8){
                            //已经到达了目的地
                            //产生新目的地
                            int x = rand.nextInt(800+f.getWidth())-f.getWidth();
                            int y = rand.nextInt(480+f.getHeight())-f.getHeight();
                            f.setTarget(new Point(x,y));

                            //产生了新目标,又有可能需要转变方向
                            f.setDirection(GameUtil.getDirectionByPoint(new Point(newX,newY),f.getTarget()));
                        }
                        //移动之后,将鱼设置到新位置
                        f.setPoint(new Point(newX,newY));
                 }
                 try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    //重画界面
                    GameJPanel.this.repaint();

            }
        }
    }

这是Fish类

 package eatfish;

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;

public class Fish {
    private String state;
    private int level;
    private Point point;
    private Point target;
    public BufferedImage[] img;
    private int direction=GameUtil.Direction_Left;
    private boolean dead;
    private Rectangle area;
    private  int width;
    private int height;
    private int drawCount;
    private int drawIndex;

    public void setPoint(Point point){
        this.point=point;
    }

    public Point getPoint(){
        return point;
    }

    public int getWidth(){
        return width;
    }

    public int getHeight(){
        return height;
    }

    public Rectangle getArea(){
        Rectangle rect=new Rectangle();
        Point p=new Point();
        p.x=this.getPoint().x;
        p.y=this.getPoint().y+this.getHeight()/3;
        rect.setLocation(p);
        rect.setSize((int)(this.getWidth()/3),(int)(this.getHeight()/3));
        this.area=rect;
        return area;
    }

    public boolean isDead(){
        return dead;
    }

    public void setDead(boolean dead){
        this.dead=dead;
    }

    public void setLevel(int level){
        this.level=level;
    }

    public int getLevel(){
        return level;
    }

    public int getDirection(){
        return direction;
    }

    public void setDirection(int direction){
        if(this.direction!=direction){
            this.setState(GameUtil.State_Turn);
        }
        this.direction=direction;
    }

    public Point getTarget(){
        return target;
    }

    public void setTarget(Point target){
        this.target=target;
    }

    public String getState(){
        return state;
    }

    public void setDrawCount(int drawCount){
        this.drawCount=drawCount;
    }

    public int getDrawCount(){
        return drawCount;
    }

    public void setDrawIndex(int drawIndex){
        this.drawIndex=drawIndex;
    }

    public int getDrawIndex(){
        return drawIndex;
    }

    public void setState(String state){
        if(this.state!=state){
            switch(state){
                case GameUtil.State_Swin:{this.setDrawCount(15);this.setDrawIndex(0);}
                case GameUtil.State_Turn:{this.setDrawCount(5);this.setDrawIndex(0);}
                case GameUtil.State_Eat:{this.setDrawCount(5);this.setDrawIndex(0);}
            }
            }
        this.state=state;
        }

    public BufferedImage getImage(){
        return img[drawIndex];
    }

    public void setImage(BufferedImage[] img){
        this.img=img;
    }

    }

    /*BufferedImage image;
    GameJPanel panel;
    int DrawIndex=1;
    String path;
    public Fish(GameJPanel panel){

    }
    public void swim(BufferedImage img){
        for(int i=1;i<15;i++){
        path="image/1/swim/swim_cycle."+i+".png";
         try {
                image=ImageIO.read(new File(path));
                this.image=img;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public BufferedImage getImage() {
        return this.image;
    }*/

解决方案

说明你的线程类可能占用了大量 CPU 的使用,从而导致卡的现象出现。
分析一下你的线程吧,必要的时候增加一些延时,或者使用同步机制阻塞一下线程,给 UI 足够的处理时间这样就不会出现你所说的现象。

时间: 2025-01-26 21:57:51

明明只建立了一个线程类,为何进行时这么卡,而且没有转头效果的相关文章

线程休眠java-一个线程类休眠1000毫秒和一个线程对象休眠1000毫秒有什么联系吗

问题描述 一个线程类休眠1000毫秒和一个线程对象休眠1000毫秒有什么联系吗 一个线程类休眠1000毫秒和一个线程对象休眠1000毫秒有什么联系吗 只有线程类及其子类对象才可以调用sleep方法吗 Thread.sleep(1000); Thread thread =new Thread ( ); thread.sleep(1000); 解决方案 本质上sleep是Thread类的静态方法,这两行代码是一样的含有,但是第二种thread.sleep的调用会报警告的:The static met

Delphi中的线程类 - TThread详解&lt;转&gt;

Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchronize的用法就完了.然而这并不是多线程编程的全部,我写此文的目的在于对此作一个补充.线程本质上是进程中一段并发运行的代码.一个进程至少有一个线程,即所谓的主线程.同时还可以有多个子线程.当一个进程中用到超过一个线程时,就是所谓的"多线程".那么这个所谓的"一段代码"

限制在同一台电脑上只允许有一个用户登录系统

在web应用系统中,出于安全性考虑,经常需要对同一客户端登录的用户数量和一个客户同时在多个客户端登陆进行限制.具体一点就是:    1.在同一台电脑上一次只允许有一个用户登录系统,2.一个用户在同一时间只允许在一个客户端登录.     我最近做的一个系统就遇到了这样的问题,本来系统已经开发完成了,但是安全测评没有通过,就是因为没有做这两个限制.怎么来做这样的限制呢?我在网上找了很久,发现问这个问题的人很多,但是没有找到特别清楚的答案.后来自己摸索着,看了一些书,终于找到解决办法了.     要解

Delphi中的线程类(1)

Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数 Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再 说明一下Execute的实现和Synchronize的用法就完了.然而这并不是多线程编程的全部,我写此文的目的在于对此作一个补充. 线程本质上是进程中一段并发运行的代码.一个进程至少有一个线程,即所 谓的主线程.同时还可以有多个子线程.当一个进程中用到超过一个线程时,就 是所谓的"多线程". 那么这个所谓的"一段代码

java中获取另一个线程中的信息

在进行多线程编程中,比较重要也是比较困难的一个操作就是如何获取线程中的信息.大多数人会采取比较常见的一种方法就是将线程中要返回的结果存储在一个字段中,然后再提供一个获取方法将这个字段的内容返回给该方法的调用者.如以下的ReturnThreadInfo类: package threadtest1; public class ReturnThreadInfo extends Thread { private String str; public ReturnThreadInfo() { this.s

JAVA 线程 开启线程 一个类里只开一个线程的简单办法

进程和线程一样,可以多个.进程是静态的,一个进程里可以有多个线程.   起动线程有两个方法:一个是接口RUNABLE,一个是继承THERAD   public class testthread{ public static void main(){ Runner1 r = new Runner1(); Thread t = new Thread(r); t.start; } class Runner1 implements Runnable{ public void run(){ .......

如何建立一个产品类的网站

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 本人在SEO界也做了一年了,之前都是做一些娱乐站,靠广告的收入维持大学的生活也绰绰有余.但到现在我才发现,所有的SEO最终的目的还是电子商务.一个产品为什么在你的网站上发布广告,就是国为产品可以通过你的网站来达到销售的目的.而我们这一些发布广告的如果自己作产品岂不是更好.于是我开始做了自己的产品的网站.我本身不是什么产品的产商,但我的家人开了

ios-iOS:请问一个线程涉及2个类,如何向该线程performSelecto?

问题描述 iOS:请问一个线程涉及2个类,如何向该线程performSelecto? 我有一个线程,这线程首先是在a类中创建,并调用a类的a1方法,而a1方法又调用了b类的b1方法. 我在c类中,想向该线程发通知,希望其调用b类的b2方法, 我的代码: [self performSelector:@selector(b2) onThread:m_thread withObject:nil waitUnitilDone:NO]; 提示:unrecognized selector to instan

调用-以下的PrintTxt是自己建立的一个类吗

问题描述 以下的PrintTxt是自己建立的一个类吗 调用方式 PrintTxt simple = new PrintTxt(""D://Mainsoft//12.txt""txt""); 解决方案 没听说PrintTxt这个类,应该是你看到的代码中作者自己写的. 解决方案二: PrintTxt 是不是自己建立的一个类,要看编译器是否在编译时出错?如果不错,且你找不到这个类的源代码,说明就不是你自己建立的类.别人建立的,或系统提供的.如果出错,说