TIE绘制图形的文件保存实现

本文介绍如何使用Flash将绘图板上的图形保存为JPG格式并导出至服务器,涉及BitmapData类的draw方法及JPEGEncoder类的使用。
 

要求效果

1、点击绘图工具栏的文件保存按钮,会弹出一个页面显示用户绘制好的JPG格式的图像,而后用户可自行保存。

主要思想

1、将绘图板上的图形保存到一个位图图像中,这通过BitmapData类的draw()方法实现。

2、将位图数据编码成JPG图像,这通过mx.graphics.codec.JPEGEncoder类实现。

3、将jpg数据保存到ByteArray(字节数组)类型的对象中。

4、最关键的是这一步,新建一个HTTP请求,设置其url属性为处理图像数据的jsp页面地址;设置其data属性为上述的字节数组;设置其发送 数据的类型属性contentType为application/octet-stream;设置其发送方法为POST(因为GET方法不能发送二进制数 据)。

5、调用navigateToURL(request,"_blank")来在新窗口中打开目标jsp页面,此时后台已生成jpg文件,jsp文件接着调用response.sendRedirect()方法跳转到jpg文件的url地址。

存在的问题

navigateToURL在IE浏览器中不起作用,不过jpg文件一样能在后台生成。

上代码!

 

 

  1. package  file
  2. {
  3.      import  flash.display.BitmapData; //用于存储位图数据
  4.      import  flash.display.DisplayObject;
  5.      import  flash.utils.ByteArray; //存储编码好的JPG位图字节
  6.      import  flash.net.*; //flash网络相关功能
  7.      import  mx.graphics.codec.JPEGEncoder; //重要:将位图数据压缩成JPG格式
  8.     
  9.     
  10.     
  11.      public   class  Export
  12.     {
  13.          //flash发送的jpg数据由这个jsp来处理
  14.          private   static   const  UPLOAD_PAGE:String= "http://localhost:8080/upload.jsp" ;     
  15.          public  function Export()
  16.         {
  17.              
  18.         }
  19.         
  20.         
  21.          public   static  function exportJpg(panel:DisplayObject): void   //以画板中的矢量图形为输入
  22.         {
  23.              //初始化一个大小跟画板一样的位图对象
  24.             var bmpData:BitmapData =  new  BitmapData(panel.width, panel.height,  true0x00FFFFFF );
  25.              //将画板中的矢量图形绘制到位图对象中
  26.             bmpData.draw(panel);
  27.              //初始化一个JPG编码器
  28.             var jpgEncoder:JPEGEncoder =  new  JPEGEncoder( 80 );
  29.              //用JPG编码器对绘制好的位图编码,并将结果保存到一个字节数组中
  30.             var imgByteArray:ByteArray = jpgEncoder.encode(bmpData);
  31.             
  32.              //初始化一个HTTP请求,将处理jpg图像的jsp页面作为其初始值
  33.             var request:URLRequest =  new  URLRequest(UPLOAD_PAGE);
  34.             
  35.              //data值就为图片编码数据imgByteArray;
  36.             request.data = imgByteArray;
  37.              //注意!!只有POST方法可以携带二进制数据,GET方法不行!
  38.             request.method = URLRequestMethod.POST;
  39.              //这个是关键,内容类型必须是下面文件流形式;
  40.             request.contentType =  "application/octet-stream" ;
  41.             
  42.              //在新窗口中打开处理图像的jsp页
  43.             navigateToURL(request, "_blank" );
  44.         }
  45.     }
  46. }

jsp页面代码

 

 

  1. <%@ page contentType= "text/html; charset=utf-8"  language= "java" %>
  2. <%@ page import= "java.util.*" %>
  3. <%@ page import= "java.io.*" %>
  4. <%
  5. int  v;
  6. long  mill = System.currentTimeMillis();
  7. String filename = mill +  ".jpg" ;
  8. //request.getRealPath方法用于获取该jsp在服务器上的文件系统绝对路径(不是http根目录!)
  9. String filePath = request.getRealPath(filename);
  10. //由request.getInputStream()实现JPG图像由flash到jsp的传递
  11. BufferedInputStream inputStream =  new  BufferedInputStream(request.getInputStream());
  12. //文件保存到跟jsp想同的目录下,当然这也是可以随业务更改的
  13. FileOutputStream outputStream =  new  FileOutputStream( new  File(filePath));
  14. //分配一个1024字节的缓冲区,将JPG数据写入输出文件
  15. byte  [] bytes =  new   byte [1024];
  16. while ((v=inputStream.read(bytes))>0){
  17.     outputStream.write(bytes,0,v);
  18. }
  19. outputStream.close();
  20. inputStream.close();
  21. //将浏览器重定位到新生成的jpg图片的URL地址
  22. response.sendRedirect( "http://localhost:8080/"  + filename);
  23. %>

 

 

import os import random class TicTacToe: def __init__(self): self.board = [" "] * 9 self.current_player = "X" self.game_mode = "" def clear_screen(self): os.system('cls' if os.name == 'nt' else 'clear') def print_title(self): print("\n" + "=" * 30) print("井字棋游戏") print("=" * 30) def print_board(self, show_numbers=False): print() if show_numbers: board_display = [str(i+1) if cell == " " else cell for i, cell in enumerate(self.board)] else: board_display = self.board.copy() for i in range(0, 9, 3): row = board_display[i:i+3] print(" " + " | ".join(row)) if i < 6: print("-----------") print() def select_game_mode(self): while True: self.clear_screen() self.print_title() print("选择游戏模式:") print("1. 单人游戏 (对战AI)") print("2. 多人游戏") choice = input("请输入选项 (1-2): ") if choice == "1": self.game_mode = "single" print("\n已选择单人模式") return elif choice == "2": self.game_mode = "multi" print("\n已选择多人模式") return else: print("无效选择,请输入1或2") def get_player_move(self): while True: try: move = input(f"玩家 [{self.current_player}]的回合,请输入位置 (1-9或 q退出): ") if move.lower() == "q": return "quit" pos = int(move) - 1 if 0 <= pos <= 8: if self.board[pos] == " ": return pos print("该位置已被占用,请重新选择!") else: print("请输入1-9之间的数字!") except ValueError: print("无效输入,请输入数字或 'q'退出!") def get_ai_move(self): # 优先选择获胜位置 for i in range(9): if self.board[i] == " ": # 尝试在这个位置落子 self.board[i] = "O" if self.check_winner() == "O": self.board[i] = " " # 撤销尝试 return i self.board[i] = " " # 撤销尝试 # 防止对手获胜 for i in range(9): if self.board[i] == " ": # 尝试玩家在这个位置落子 self.board[i] = "X" if self.check_winner() == "X": self.board[i] = " " # 撤销尝试 return i self.board[i] = " " # 撤销尝试 # 优先选择中心位置 if self.board[4] == " ": return 4 # 然后选择角落位置 corners = [0, 2, 6, 8] empty_corners = [pos for pos in corners if self.board[pos] == " "] if empty_corners: return random.choice(empty_corners) # 最后选择边缘位置 edges = [1, 3, 5, 7] empty_edges = [pos for pos in edges if self.board[pos] == " "] if empty_edges: return random.choice(empty_edges) # 如果以上都不适用,选择第一个空位 for i in range(9): if self.board[i] == " ": return i return 0 # 默认返回,这种情况不应该发生 def check_winner(self): wins = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ] for a, b, c in wins: if self.board[a] != " " and self.board[a] == self.board[b] == self.board[c]: return self.board[a] if " " not in self.board: return "Tie" return None def play_game(self): self.select_game_mode() while True: self.board = [" "] * 9 self.current_player = "X" self.clear_screen() self.print_title() print("位置布局参考:") self.print_board(show_numbers=True) print("输入1-9选择位置,输入 'q'可以随时退出\n") while True: self.print_board() # 获取移动 if self.game_mode == "single" and self.current_player == "O": move = self.get_ai_move() print(f"AI玩家选择了位置 {move + 1}") else: move = self.get_player_move() if move == "quit": print("\n游戏已退出!") return # 更新棋盘 self.board[move] = self.current_player self.clear_screen() self.print_title() # 检查游戏状态 result = self.check_winner() if result: self.print_board() if result == "Tie": print("===平局!游戏结束! ===") else: if self.game_mode == "single" and result == "O": print("===AI获胜! ===") else: print(f"===玩家 [{result}]获胜! ===") break # 切换玩家 self.current_player = "O" if self.current_player == "X" else "X" # 询问是否重玩 restart = input("\n是否重新开始?(y/n): ").lower() if restart != 'y': print("\n感谢游玩!再见!") return # 重新选择模式 self.select_game_mode() if __name__ == "__main__": game = TicTacToe() game.play_game()这个代码按照1. 游戏规则实现 创建3x3棋盘数据结构,支持玩家交替输入"X"和"O" 实现胜负判断逻辑:检查横向、纵向、对角线是否有连续三个相同符号 处理平局条件:棋盘填满且无玩家获胜时结束游戏 2. 用户交互功能 通过控制台输入坐标(如1-9或行列数字)进行落子 实时显示棋盘状态,每次落子后刷新界面 输入合法性校验:位置是否已被占用、输入是否为有效数字等 3. 代码规范 扩展要求(20%) 1. 图形化界面(二选一) 基础版:使用turtle库绘制棋盘和棋子 进阶版:通过PyGame或Tkinter实现交互式界面 2. 人机对战模式 简单AI:随机选择空位落子 高级AI:实现Minimax算法或启发式策略,确保AI不输(参考网页3的决策树逻辑) 3. 游戏记录与复盘 保存每局对战记录(如落子顺序、胜负结果) 支持回放历史对局 这个要求重新生成
06-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值