Java多线程之赛跑游戏(含生成exe文件)
在JavaSE中,多线程是一个重要的内容。
我们要了解多线程的概念,就要先了解进程的概念;要了解进程的概念,就离不开操作系统的概念。
在一台正常运行的电脑中,计算机硬件(如CPU、内存、硬盘、网卡、显示器、键盘、鼠标等)提供了基础的硬件环境;在硬件之上,是操作系统,这是系统级的软件程序,用来管理计算机的各项软件资源,是人机交互中的关键环节;在操作系统之上,则是各类应用软件程序,比如QQ、微信、浏览器等。
进程是一个动态的概念,程序则是一个静态的概念。程序在操作系统中运行起来时,需要操作系统为其分配相应的内存、CPU等资源,成为进程。不同的进程,独享各自的内存、CPU等资源。这也是进程安全性所不可缺少的。所以,进程是操作系统分配CPU及各类系统资源的基本单位。
当进程运行起来时,通常会有多个子任务,以游戏为例,里面需要绘制游戏面板,如果游戏里有多个角色的人物进行并发活动,还需要能够获得相应的CPU资源,从而取得CPU的执行权,以进入运行状态。同时,在同一个游戏中,每个角色的有关状态数据,可以为该游戏中的其他角色所获取。由此可见,一个进程中可以有多个子任务,这些子任务需要并发轮流获取CPU的执行权,同时可以共享进程的内存资源。进程中的这些子任务就被称为线程,多个子任务就是多个线程。线程是进程中分配CPU资源的基本单位,线程不可以脱离进程而存在。
Java语言本身就是一种多线程语言。比如,在JavaSE的一个Java工程中,JVM通过main入口函数运行起来时,同时还会有GC(垃圾回收器)运行起来,以等待回收Java堆内存中变为垃圾的对象,以节省堆内存空间。
在做完上述知识铺垫和准备后,我接下来通过一个赛跑游戏,来为大家演示Java多线程的运用。
在这里,我先将该赛跑游戏的运行效果予以演示:
每次登录该游戏,会弹出一个提示框,告知用户是第几次登录,并有温馨提示。
点击“确定”或关闭该提示框,则进入游戏界面。该界面分为上下两部分,上半部分为游戏跑道,4个赛手,共4个跑道;下半部分为游戏控制面板,提示用户选择赛手,输入押注金额,以及点击“开始”按钮开始赛跑,还有“重新开始”按钮以回到比赛准备的状态等。
点击“开始”按钮后,进入赛跑游戏,游戏面板中的4个赛手开始奔跑,对于先跑到终点的赛手,会弹出提示框予以庆祝;如果用户押注失败,则用户本金会予以相应减少;如果用户押注成功,则用户本金会予以相应增加。
好了,演示完上述游戏后,接下来谈下开发思路。
首先,完成游戏前端部分。先绘制一个游戏窗体,窗体上添加面板,面板上添加各类所需的组件。
其次,游戏前端部分完成后,根据面向对象的思想,将赛手抽象为一个类,将与赛手有关的各种属性与功能均由该类实现;同时,主线程负责绘制游戏前端,各个赛手要运行时,则通过开辟子线程来实现。
再次,当赛跑游戏结束时,根据产生的第一名,刷新本金,弹出庆祝框,同时提示用户是成功或者失败;此外,将用户的本金与登录次数存入一个属性文件,用户本金与登录次数的变化会实时更新到属性文件中。
Step 1
请看游戏前端代码:
package runningGame; import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.Properties;
import java.util.ResourceBundle; import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField; /**
* 游戏 面板设计
* @author 李章勇
* 常量分析:
* 4个赛手
* 赛手编号
* 胜利感言
* 跑道面板
* 4个跑道,每个跑道一张背景图
* 每个跑道上各有一个准备状态的赛手
* 终点线
* 控制面板
* 4个单选按钮[表示赛手】
* 提示选择赛手、输入押注,押注输入框
* 我的本金提示
* 开始按钮,重新开始按钮
* 多个子线程共用同一段代码,赛手类
*/
public class GameJFrame extends JFrame{
//赛道背景面板
GamePanel jp_game=new GamePanel();
//4张跑道背景图
Image[] img_back=new Image[StaticIntString.NUM];
//每个跑道上处于准备状态的小人
Image[] img_ready=new Image[StaticIntString.NUM];
//每个跑道上奔跑中的小人
Image[] img_run=new Image[StaticIntString.NUM]; //游戏控制面板
JPanel jp_control=new JPanel();
//4个单选按钮
static JRadioButton[] jrb_mans=new JRadioButton[StaticIntString.NUM];
//按钮组
ButtonGroup bg=new ButtonGroup();
//提示选择姓名并输入金额
JLabel jl_inputTips=new JLabel(StaticIntString.INPUT_TIPS1);
//输入押注金额
JTextField jtf_cost=new JTextField(10);
JLabel jl_winFailTips=new JLabel("本次输赢:");
JLabel jl_winFail=new JLabel(StaticIntString.WIN_FAIL);
//本金提示
JLabel jl_ownMoneyTips=new JLabel("我的本金:");
static Properties pro=new Properties();
//从属性文件里读取本金
static ResourceBundle resource=ResourceBundle.getBundle("runningGame.infos");
String ownMoney=resource.getString("ownMoney");
BigInteger bi_times=new BigInteger(resource.getString("times"));
static BigInteger bi_bankruptcy=new BigInteger(resource.getString("bankruptcy"));
String ownMoney_System=resource.getString("ownMoney_System");
//本金
JLabel jl_ownMoney=new JLabel(ownMoney);
//开始按钮
JButton jbt_start=new JButton("开始");
//重新开始按钮
JButton jbt_restart=new JButton("重新开始");
static String selectedName;
RunningMan[] mans=new RunningMan[StaticIntString.NUM]; public GameJFrame() {
if(bi_times.toString().equals("1")){
JOptionPane.showMessageDialog(this, "首次登陆,欢迎光临!\n系统赠予您10000元,\n祝您玩得开心愉快!\n只是玩玩,不要沉溺赌博哦");
}else{
JOptionPane.showMessageDialog(this, "您这是第 "+bi_times.toString()+" 次登陆,欢迎光临!\n祝您玩得开心愉快!\n只是玩玩,不要沉溺赌博哦");
}
bi_times=bi_times.add(new BigInteger("1"));
try {
BufferedInputStream fis=new BufferedInputStream(new FileInputStream("src//runningGame//infos.properties"));
BufferedOutputStream fos=new BufferedOutputStream(new FileOutputStream("src//runningGame//infos.properties"));
String ownMoney_System=resource.getString("ownMoney_System");;
try {
pro.load(fis);
} catch (IOException e1) {
e1.printStackTrace();
}
pro.setProperty("times", bi_times.toString());
pro.setProperty("ownMoney", ownMoney);
pro.setProperty("bankruptcy", bi_bankruptcy.toString());
pro.setProperty("ownMoney_System", ownMoney_System);
try {
pro.store(fos, "");
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} for(int i=0;i<StaticIntString.NUM;i++){
img_back[i]=Toolkit.getDefaultToolkit().createImage("imgBack//"+(i+1)+".jpg");
img_ready[i]=Toolkit.getDefaultToolkit().createImage("imgReady//"+(i+1)+"2.gif");
img_run[i]=Toolkit.getDefaultToolkit().createImage("imgRun//"+(i+1)+"1.gif");
jrb_mans[i]=new JRadioButton(StaticIntString.NAMES[i]);
bg.add(jrb_mans[i]);
jp_control.add(jrb_mans[i]);
}
jbt_start.addActionListener(new ActionListener(){
boolean isSelected=false;
public boolean judgeSelected(){
for(JRadioButton j:jrb_mans){
if(j.isSelected()){
isSelected=true;
}
}
return isSelected;
} @Override
public void actionPerformed(ActionEvent arg0) {
if(!judgeSelected()){
JOptionPane.showMessageDialog(GameJFrame.this, "您还没选人呢",
"看着点", JOptionPane.WARNING_MESSAGE);
return;
}
if(jtf_cost.getText().trim().length()==0){
JOptionPane.showMessageDialog(GameJFrame.this, "您还没下注呢",
"看着点", JOptionPane.WARNING_MESSAGE);
return;
}
char[] cs=jtf_cost.getText().toCharArray();
for(int i=0;i<cs.length;i++){
if(cs[i]<'0' || cs[i]>'9'){
JOptionPane.showMessageDialog(GameJFrame.this, "您输入的不是数字",
"看着点", JOptionPane.WARNING_MESSAGE);
jtf_cost.setText("");
return;
}
if(cs[0]=='0'){
JOptionPane.showMessageDialog(GameJFrame.this, "数字首位不能是0",
"看着点", JOptionPane.WARNING_MESSAGE);
jtf_cost.setText("");
return;
}
}
BigInteger bi_jtf_cost=new BigInteger(jtf_cost.getText());
BigInteger bi_jl_ownMoney=new BigInteger(jl_ownMoney.getText()); if((bi_jtf_cost.compareTo(bi_jl_ownMoney))>0){
JOptionPane.showMessageDialog(GameJFrame.this, "您的下注金额不能超过本金哦",
"看着点", JOptionPane.WARNING_MESSAGE);
jtf_cost.setText("");
return;
} for(JRadioButton j:jrb_mans){
if(j.isSelected()){
selectedName=j.getText();
break;
}
}
for(JRadioButton j:jrb_mans){
j.setEnabled(false);
} jtf_cost.setEditable(false);
jl_inputTips.setText(StaticIntString.INPUT_TIPS2);
jbt_restart.setEnabled(true);
jbt_start.setEnabled(false);
RunningMan.isEnd=false;
RunningMan.canRun=true;
RunningMan.num=0;
for(int i=0;i<StaticIntString.NUM;i++){
mans[i].img=img_run[i];
mans[i].start();
}
}
});
jbt_restart.addActionListener(new ActionListener(){ @Override
public void actionPerformed(ActionEvent arg0) { for(int i=0;i<StaticIntString.NUM;i++){
jrb_mans[i].setText(StaticIntString.NAMES[i]);
jrb_mans[i].setEnabled(true);
}
jl_inputTips.setText(StaticIntString.INPUT_TIPS1);
jtf_cost.setText("");
jtf_cost.setEditable(true);
jl_winFail.setForeground(Color.BLACK);
jl_winFail.setText(StaticIntString.WIN_FAIL);
jbt_start.setEnabled(true);
jbt_restart.setEnabled(false);
RunningMan.isEnd=true;
RunningMan.canRun=false;
bg.clearSelection();
for(int i=0;i<StaticIntString.NUM;i++){
mans[i]=new RunningMan(StaticIntString.NAMES[i], 0, (jp_game.getHeight()*i)/4+30, img_ready[i], GameJFrame.this);
}
}
}); jp_control.setBorder(BorderFactory.createTitledBorder("游戏控制系统"));
jp_control.add(jl_inputTips);
jp_control.add(jtf_cost);
jp_control.add(jl_winFailTips);
jp_control.add(jl_winFail);
jp_control.add(jl_ownMoneyTips);
jp_control.add(jl_ownMoney);
jp_control.add(jbt_start);
jp_control.add(jbt_restart);
this.add(jp_game,BorderLayout.CENTER);
this.add(jp_control, BorderLayout.SOUTH);
setResizable(false);
setTitle("赛跑游戏 ---作者:李章勇");
setBounds(200, 100, 1000, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
for(int i=0;i<StaticIntString.NUM;i++){
mans[i]=new RunningMan(StaticIntString.NAMES[i], 0, (jp_game.getHeight()*i)/4+30, img_ready[i], this);
}
} class GamePanel extends JPanel{
@Override
public void paint(Graphics g) {
super.paint(g);
for(int i=0;i<StaticIntString.NUM;i++){
g.drawImage(img_back[i], 0, (this.getHeight()*i)/4,this.getWidth(),this.getHeight()/4+30,this);
mans[i].drawSelf(g, this); }
g.setColor(Color.RED);
g.fillRect(850, 0, 5, this.getHeight());
}
} public static void main(String[] args) {
new GameJFrame();
}
}
Step 2
将赛手抽象为一个类,同时创建一个接口工具,存储常数,便于对数据的统一管理;再创建一个名为“infos.properties”的属性文件,将用户本金、登录次数等信息存储到属性文件里,以备更新。
package runningGame; public interface StaticIntString {
public static final int NUM=4;
public static final String[] NAMES={ "1号选手", "2号选手", "3号选手", "4号选手" };
public static final String[] WINS={ "预测未来的最好方法,就是创造未来.", "人生重要的不是所站的位置,而是所朝的方向.",
"如你想要拥有完美无暇的友谊,可能一辈子找不到兄弟姐妹","正因年轻咱们一无所有,也正正因年轻咱们将拥有一切." };
public static final String INPUT_TIPS1="请选择赛手并输入金额:";
public static final String INPUT_TIPS2="本次下注金额:";
public static final String GET_WIN="[获胜]";
public static final String WIN_FAIL="[Win/Fail]";
public static final String WIN_STATE="[Win]";
public static final String FAIL_STATE="[Fail]";
}
属性文件infos.properties:
#破产次数,登录次数,系统默认赠予的本金,用户的实际本金;只要用户本金小于等于0,系统会自动为用户赠予初始本金。
#Fri Dec 01 09:34:34 CST 2017
bankruptcy=0
times=1
ownMoney_System=10000
ownMoney=10000
赛手类RunningMan:
package runningGame; import java.awt.Graphics;
import java.awt.Image;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Random; import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton; /**
* 赛手的属性:姓名,坐标(x/y),自身图像,准备状态的图像,关联的窗体
* 位移所需的随机数Random,
* 第一名NO1
* 是否能跑的状态canRun
* 比赛是否结束isEnd
* 每个赛手跑完时计数num
*
* 赛手画自己的方法drawSelf
* 赛手跑步位移的方法move
* 子线程运行的run方法
*
* @author 李章勇
*
*/
public class RunningMan extends Thread {
public String name;
private int x_point,y_poinit;
public Image img;
private Image imgReady;
private GameJFrame jf_game;
static Random rand=new Random();
static RunningMan NO1;
static boolean canRun=true;
static boolean isEnd=false;
static int num=0;
static BigInteger bi_ownMoney; public RunningMan(String name,int x_point,int y_point,Image img,GameJFrame jf_game) {
this.name=name;
this.x_point=x_point;
this.y_poinit=y_point;
this.img=img;
this.imgReady=img;
this.jf_game=jf_game;
} public void setName2(String name){
this.name=name;
}
public String getName2(){
return name;
} public void drawSelf(Graphics g,JPanel jp){
g.drawImage(img, x_point, y_poinit, jp);
} public void move(){
x_point+=10+rand.nextInt(30);
} @Override
public void run() {
while(x_point<=850 && canRun){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
move();
}
synchronized(String.class){
if(canRun){
x_point=850;
img=imgReady;
num++;
}
if(!isEnd){
NO1=this;
isEnd=true;
}
if(num==4){
System.out.println("本次比赛第一名:"+NO1.name);
//根据比赛结果,修改金额 类
bi_ownMoney=new GetResult(jf_game).getRightMoney();
new WinDialog();
try {
BufferedInputStream fis = new BufferedInputStream(new FileInputStream("src//runningGame//infos.properties"));
BufferedOutputStream fos=new BufferedOutputStream(new FileOutputStream("src//runningGame//infos.properties"));
try {
GameJFrame.pro.load(fis);
if((bi_ownMoney.compareTo(new BigInteger("0"))<=0)){
JOptionPane.showMessageDialog(jf_game, "您已没有本金,\n系统不差钱儿,再次赠予您 10000 元!\n祝您玩得开心哦!",
"看着点", JOptionPane.WARNING_MESSAGE);
jf_game.jl_ownMoney.setText(GameJFrame.resource.getString("ownMoney_System"));
GameJFrame.pro.setProperty("ownMoney", GameJFrame.resource.getString("ownMoney_System"));
BigInteger bi_bankruptcy=new BigInteger(GameJFrame.resource.getString("bankruptcy")).add(new BigInteger("1"));
GameJFrame.pro.setProperty("bankruptcy", bi_bankruptcy.toString()); }else{
jf_game.jl_ownMoney.setText(bi_ownMoney.toString());
GameJFrame.pro.setProperty("ownMoney", bi_ownMoney.toString());
}
GameJFrame.pro.store(fos, "");
fis.close();
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
for(JRadioButton j:GameJFrame.jrb_mans){
if(NO1.name.equals(j.getText())){
j.setText(j.getText()+StaticIntString.GET_WIN);
}
}
}
}
}
}
刷新用户本金的类:
package runningGame; import java.awt.Color;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger; import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JTextField; /**
* 需要的属性
* 代表四个赛手的按钮
* 输入的金额
* 输赢状态
* 本金
* 关联的窗体
* 获得比赛后、发生变化的钱数getRightMoney
* 设置本金新的数值setNewMoney
* @author 李章勇
*
*/
public class GetResult {
private JRadioButton[] jrb_mans;
private JTextField jtf_cost;
private JLabel jl_winFail;
private JLabel jl_ownMoney; public GetResult(GameJFrame jf_game) {
this.jrb_mans=jf_game.jrb_mans;
this.jtf_cost=jf_game.jtf_cost;
this.jl_winFail=jf_game.jl_winFail;
this.jl_ownMoney=jf_game.jl_ownMoney;
} public BigInteger getRightMoney(){
BigInteger bi_ownMoney=new BigInteger(jl_ownMoney.getText());
BigInteger bi_cost=new BigInteger(jtf_cost.getText());
if(GameJFrame.selectedName!=null && GameJFrame.selectedName.equals(RunningMan.NO1.name)){
jl_winFail.setForeground(Color.GREEN);
jl_winFail.setText(StaticIntString.WIN_STATE);
bi_ownMoney=bi_ownMoney.add(bi_cost);
jl_ownMoney.setText(bi_ownMoney.toString());
}else{
jl_winFail.setForeground(Color.RED);
jl_winFail.setText(StaticIntString.FAIL_STATE);
bi_ownMoney=bi_ownMoney.subtract(bi_cost);
jl_ownMoney.setText(bi_ownMoney.toString());
}
return bi_ownMoney;
}
}
弹出庆祝框的类WinDialog:
package runningGame; import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.util.Random; import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 对话框背景图
* 4个赛手获胜时的图片
* 自定义面板
* 随机数,随机获取胜利宣言
* @author 李章勇
*
*/
public class WinDialog extends JDialog{
Image img_back=Toolkit.getDefaultToolkit().createImage("imgWin//winbg.jpg");
Image[] img_wins=new Image[StaticIntString.NUM];
WinJPanel wp=new WinJPanel();
Random rand=new Random();
int num=0; public WinDialog() {
for(int i=0;i<img_wins.length;i++){
img_wins[i]=Toolkit.getDefaultToolkit().createImage("imgWin//"+(i+1)+"3.gif");
}
wp.setBounds(100, 100, 400, 300);
add(wp);
setTitle("胜利墙");
setBounds(300, 300, 400, 300);
setResizable(false);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setVisible(true);
num=rand.nextInt(4);
} class WinJPanel extends JPanel{ @Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(img_back, 0, 0, this.getWidth(), this.getHeight(), this); switch(RunningMan.NO1.name){
case "1号选手":
g.drawImage(img_wins[0], 50, 100, this);
break;
case "2号选手":
g.drawImage(img_wins[1], 50, 100, this);
break;
case "3号选手":
g.drawImage(img_wins[2], 50, 100, this);
break;
case "4号选手":
g.drawImage(img_wins[3], 50, 100, this);
break;
default:
break;
}
g.setColor(Color.RED);
g.drawString("本次获胜选手:"+RunningMan.NO1.name, 20, 30);
g.drawString(StaticIntString.WINS[num], 20, 50);
}
}
}
到此,代码部分就结束了。至于代码中用到的图片,读者参考下述对图片的命名规则,收集相应的图片即可。
到此,整个单机赛跑游戏是完成了。然而,目前在运行时,我们需要在Eclipse里运行项目才可以打开游戏,显然这种方式并不符合普通用户。为此,我们来看如何把项目打包成jar包后,再生成exe可执行文件,这样的话,用户只要双击运行该exe可执行文件,就可以打开游戏。
在此,介绍一款将jar文件生成exe文件时用到的第三方软件:exe4j(下载地址:http://www.ej-technologies.com/download/exe4j/files):
至于接下来应该怎样把jar包生成exe文件,有一篇博客《将java项目打包成jar包并生成可独立执行的exe文件》中已经介绍得很详细,建议读者参考。
现在,一个完整的exe版单机赛跑游戏就制作好了。
Java多线程之赛跑游戏(含生成exe文件)的更多相关文章
- Java多线程之赛跑游戏
在JavaSE中,多线程是一个重要的内容. 我们要了解多线程的概念,就要先了解进程的概念:要了解进程的概念,就离不开操作系统的概念. 在一台正常运行的电脑中,计算机硬件(如CPU.内存.硬盘.网卡.显 ...
- 如何打包/运行jar包,及生成exe文件
关于如何打包/运行jar包,以及生成exe文件.之前各种查询.博客,终于搞明白究竟是咋回事.记得还做过笔记的.今天要打包生成exe用的时候,居然忘了咋怎来着.去查看之前的笔记,死活没找到(好像被删掉了 ...
- GUI生成exe文件
gui如何生成exe文件: 已经有gui.m和gui.fig文件 1 安装编译器.已经安装好了vs10的. 2 设置编译器.在matlab命令行输入mex -setup,选择安装的c编译器 3 调用编 ...
- 如何解决exe4j生成exe文件后弹出提示信息
使用exe4j生成exe文件时会提示以上一段信息,这个主要是没有注册导致的,在welcome to exe4j的右下角有一个注册信息的地方,去找个注册码,就OK了. 通用注册码:L-g782dn2d- ...
- [原创]Matlab之GUI生成EXE文件
近期因为项目需要,简化流程,写了一些Matlab程序,并配备上了GUI界面使其简单易用.然后问题来了,可移植性.使用Matlab生成EXE文件(可以封装很多的function),然后在一台安装有Mat ...
- vs2010如何生成EXE文件如何更改EXE程序图标
vs2010如何生成EXE文件 F5启动调试后,进入下面路径查找: 我的文档\Visual Studio 2010\Projects\项目名称\项目名称\bin\Debug 如何更改EXE程序图标 其 ...
- matlab改变GUI和figure左上角图标的方法,并生成exe文件
1. GUI左上角图标的更改,假设GUI的Tag为figure1,在其OpeningFcn里添加h = handles.figure1; %返回其句柄newIcon = javax.swing.Ima ...
- pyinstaller生成exe文件失败
我的python是3.6,目前pyinstaller并不支持,有网友建议在Github上下载源码,用pyinstaller_develop文件夹替换pyinstaller安装位置下同名文件夹.这样做之 ...
- c++与matlab联合编程,调用Deploytool 生成exe文件和dll文件(转)
转自:http://www.cnblogs.com/xlw1219/archive/2012/12/25/2832222.html 首先必须知道联合编程需要知道的一些命令解释: mcc 的作用是将 . ...
随机推荐
- [您有新的未分配科技点]数位DP:从板子到基础(例题 bzoj1026 windy数 bzoj3131 淘金)
只会统计数位个数或者某种”符合简单规律”的数并不够……我们需要更多的套路和应用 数位dp中常用的思想是“分类讨论”思想.下面我们就看一道典型的分类讨论例题 1026: [SCOI2009]windy数 ...
- NHibernate 设置主键不自增长
1.Model 配置 [PrimaryKey(PrimaryKeyType.Assigned,"ID")] 2.使用时要手动赋值
- 各行业最受欢迎的编程语言,硬件最青睐C和C++
近日,HackerRank发布了2018年开发技能报告,其中探讨了一些对理解开发人员环境至关重要的事情,本文将摘录编程语言排行部分 2018 开发者技能调查:不同行业中最热门的编程语言 尽管新语言经常 ...
- 【noip2018】【luogu5024】保卫王国
题目描述 Z 国有nn座城市,n - 1n−1条双向道路,每条双向道路连接两座城市,且任意两座城市 都能通过若干条道路相互到达. Z 国的国防部长小 Z 要在城市中驻扎军队.驻扎军队需要满足如下几个条 ...
- 网络协议之DHCP与Route20170330
由于要使用网络通讯,所以不可避免的要用到dhcp.理想的网络通讯方式是下面3种都要支持: 1,接入已有网络.这便要求可以作为dhcp客户端. 2,作为DHCP服务器,动态分配IP. 3,指定固定IP ...
- 使图片水平并垂直居中的一个Hack
淘宝的一个前端面试题:使用纯CSS实现未知尺寸的图片(但高宽都小于200px)在200px的正方形容器中水平和垂直居中. 想起了vertical-align:middle;但是不行,后来才知道还要di ...
- PID控制算法的C语言实现八 变积分的PID控制算法C语言实现
变积分PID可以看成是积分分离的PID算法的更一般的形式.在普通的PID控制算法中,由于积分系数ki是常数,所以在整个控制过程中,积分增量是不变的.但是,系统对于积分项的要求是,系统偏差大时,积分作用 ...
- linux 隐藏权限
原文 ------通过chattr设置档案的隐藏权限------ [root@sdc ~]#chattr --helpUsage: chattr [-RV] [-+=AacDdijsSu] [-v v ...
- 前端PHP入门-027-数组常用函数-掌握级别
下面的函数一定要到熟悉甚至到掌握级别. 这些函数,也是面试中基础面试中最爱问到的问题. 函数名 功能 array_combine() 生成一个数组,用一个数组的值作为键名,另一个数组值作为值 rang ...
- JS中的匿名函数自执行、函数声明与函数表达式
先看一段jQuery源码中匿名函数自执行的例子: (function( window, undefined ) { // jquery code })(window); 另外一种常见的写法: +fun ...