Re: Sub Commander Project (Don)
- Posted by Derek Parnell <ddparnell at bi?pon?.com> Dec 14, 2007
- 533 views
Don, I did a little reworking on your example code. The main change was to separate painting the screen from the updating of the pixmap. They should be indepenant in order to process Windows messages properly. You should only paint the screen when Windows or your program needs to. The pixmap updating happens outside of that event. To demostrate this you can now use the Numpad + and - keys to speed up and slow down the speed of the radar sweep. Another change you need to do is to make the ship's movement independant of the radar speed. In fact, to 'move the dot' you need to calculate the position of the submarine and the position of the ship(s) based on their individual vectors and speed then translate the difference between the vectors onto the radar scope. Also, I've added a cheesy effect of having the 'dot' fade after the sweep. You cold also add a grid or vector lines onto the scope's screen to aid the player.
-- with trace include Win32Lib.ew --include mywin.ew sequence s,cen,fin,ship,stuff integer left,top,box_width,box_height,screen_width, screen_height,remain_width,A,B,r,bot,right,step, ship_dir,ship_loc,yy,dot_showing,ship_speed atom start atom pifac sequence dot_color, dot_pos integer radarpos radarpos = 0 atom timedelta integer radarspeed pifac = PI/1800 step=16 start=time() s=getRect(Screen) screen_width=s[3]-s[1] screen_height=s[4]-s[2] box_height=screen_height-54--for tab bar at bottom box_width=box_height remain_width=screen_width-box_width left=remain_width/2 right=left+box_width top=1 bot=box_height A=floor(box_width/2)+left--x B=floor(box_height/2) --y cen={A,B} r=B dot_showing = 0 dot_color = {#000000, #001100, #002200, #003300, #004400, #005500, #006600, #007700, #008800, #009900, #00AA00, #00BB00, #00CC00, #00DD00, #00EE00, #00FF00} constant Window1 = createEx( Window, "Window1", 0, s[1],s[2], s[3], s[4], 0, 0 ) constant Pix=createEx(Pixmap,"", 0, box_height,bot,s[3],bot,0,0 ) constant ButtonFace= rgb( #D4, #CF, #C6 ) procedure mPuts(integer id,integer col,integer row,sequence text) setPenPos(id,col,row) wPuts(id,text) end procedure function p2xy(atom r, atom a) -- polar to xy return {r*sin(a),-r*cos(a)} end function function vector(sequence pt1,sequence pt2)--distance and angle from pt1 to pt2 integer dx,dy atom r,a dx=floor(pt2[1]-pt1[1]) dy=floor(pt2[2]-pt1[2]) r=sqrt(dx*dx+dy*dy) if r=0 then return {0,0} end if if dy<0 then if dx<0 then a=2*PI-arctan(dx/dy) else a=-arctan(dx/dy) end if elsif dy>0 then a=PI-arctan(dx/dy) else --dy=0 (one point above the other); can't use arctan formula if dx<0 then a=3*PI/2 else a=PI/2 end if end if return {r,1800*a/PI} --convert radians to decidegrees end function function get_ship_dir(sequence shp) stuff=vector(cen,shp) return floor(stuff[2]) end function function get_ship_dist(sequence shp) stuff=vector(cen,shp) return floor(stuff[1]) end function ----------------------------setup ship-------------------------------- --sub is heading do North and not moving ship_loc=rand(r) ship_dir=rand(3600) ship=cen+p2xy(ship_loc,ship_dir * pifac) -- this the beging ship location ship_dir=rand(3600)--the direction the ship will travel ship_speed=40 + rand(20) ---------------------------------------------------------------------- procedure print_info1() mPuts(Pix,1,1,sprintf("screen_width=%d",screen_width)) mPuts(Pix,1,12,sprintf("box_width=%d",box_width)) mPuts(Pix,1,24,sprintf("remain=%d",remain_width)) mPuts(Pix,1,36,sprintf("used=%d",box_width+remain_width)) mPuts(Pix,1,48,sprintf("left=%d",left*2)) end procedure procedure print_info2() mPuts(Pix,1,58,sprintf("A=%d",A)) mPuts(Pix,1,70,sprintf("B=%d",B)) mPuts(Pix,1,90,sprintf("12 o'clk=%d,%d,%d,%d",{A,B,A,top})) mPuts(Pix,1,110,sprintf("3 o'clk=%d,%d,%d,%d",{A,B,right,B})) mPuts(Pix,1,130,sprintf("6 o'clk=%d,%d,%d,%d",{A,B,A,bot})) mPuts(Pix,1,150,sprintf("9 o'clk=%d,%d,%d,%d",{A,B,left,B})) mPuts(Pix,1,170,sprintf(" radius=%d",A)) -- mPuts(Pix,1,190,sprintf("circum=%d",pi*r*pi*r)) end procedure procedure print_time() setPenColor(Pix,ButtonFace) drawRectangle(Pix,1,31,210,120,230) setPenColor(Pix,Black) mPuts(Pix,1,210,sprintf("Time=%.2f",time()-start)) end procedure procedure print_ship_info() sequence lTextA, lTextB sequence lTextASize, lTextBSize integer lTX, lTY, lTW, lTH lTextA = sprintf("s[1]=%d s[2]=%d",{ship[1],ship[2]}) lTextASize = getTextExtent(Pix, lTextA) lTextB = sprintf("deg=%d rad=%d, spd=%d",{get_ship_dir(ship),get_ship_dist(ship), ship_speed}) lTextBSize = getTextExtent(Pix, lTextB) lTX = 1 lTY = 236 if lTextASize[1] > lTextBSize[1] then lTW = lTextASize[1] else lTW = lTextBSize[1] end if lTH = lTextASize[2] * 2 setPenColor(Pix,ButtonFace) drawRectangle(Pix,1, lTX, lTY - lTextASize[2], lTX + lTW + 10 , lTY + lTH * 2) setPenColor(Pix,Black) mPuts(Pix,lTX, lTY, lTextA) mPuts(Pix,lTX, lTY + lTH, lTextB) end procedure procedure move_dot() ship=ship+p2xy(9,ship_dir * pifac) end procedure procedure clear_dot() if dot_showing > 1 then dot_showing -= 1 setPenColor(Pix, dot_color[dot_showing]) ship=floor(ship) drawEllipse(Pix,1,dot_pos[1], dot_pos[2], dot_pos[3],dot_pos[4]) end if end procedure with trace procedure print_dot() integer prob if dot_showing > 1 then dot_showing = 2 clear_dot() end if -- Calculate probabilty of seeing ship depending on radar speed. -- The faster the radar the less likely to see the ship. -- Speed 1 (slowest) --> probability: 105% -- Speed 300 (fastest) --> probability: 10% prob = 301 - radarspeed prob = floor(power(prob,3)/200000-(power(prob,2))/416+prob/1.7+10) if rand(100) >= prob then return end if setPenColor(Pix, dot_color[$]) ship=floor(ship) dot_pos = {ship[1]-5,ship[2]-5,ship[1]+5,ship[2]+5} drawEllipse(Pix, 1, dot_pos[1], dot_pos[2], dot_pos[3],dot_pos[4]) dot_showing = length(dot_color) + 1 end procedure procedure UpdateRadar() sequence lNewFin atom lNewTime -- Only update the screen every 100th of a second. lNewTime = time() if lNewTime - timedelta < 0.01 then return end if timedelta = lNewTime if dot_showing > 0 then clear_dot() end if lNewFin = floor(cen+p2xy(r,radarpos * pifac) ) radarpos += radarspeed if compare(lNewFin, fin) = 0 then return end if if radarpos <= radarspeed then print_ship_info() end if setPenColor(Pix,Black) drawLine(Pix,cen[1],cen[2], fin[1], fin[2]) --1st line print_ship_info() fin = lNewFin if get_ship_dist(ship) < r then yy = get_ship_dir(ship) if yy <= radarpos + radarspeed then if yy >= radarpos - radarspeed then print_dot() end if end if end if setPenColor(Pix,Yellow) drawLine(Pix, cen[1], cen[2], fin[1], fin[2]) --2nd line repaintFG(Window1) if radarpos >= 3600 then move_dot() radarpos = 0 end if end procedure setHandler( Window1, w32HTimer, routine_id("Window1_onTimer")) procedure Window1_onPaint(integer self,integer event,sequence parms) copyBlt(Window1,0,0,Pix) end procedure setHandler( Window1, w32HPaint, routine_id("Window1_onPaint")) procedure Window1_onKeyDown(integer self,integer event,sequence parms) if parms[1] = VK_ADD then -- Numpad + -- Increase radar speed by 25% radarspeed += floor(radarspeed * 0.25) + 1 if radarspeed > 300 then radarspeed = 300 end if elsif parms[1] = VK_SUBTRACT then -- Numpad - -- Decrease radar speed by 25% radarspeed -= floor(radarspeed * 0.25) + 1 if radarspeed < 1 then radarspeed = 1 end if end if end procedure setHandler( Window1, w32HKeyDown, routine_id("Window1_onKeyDown")) procedure setup(integer self,integer event,sequence parms) setPenColor( Pix, Black ) print_info1() drawEllipse( Pix,1 ,left,0,box_width+left,box_height) setPenColor(Pix,Red) setPenWidth(Pix,4) drawEllipse( Pix,0 ,left,0,box_width+left,box_height) setPenWidth(Pix,1) setPenColor(Pix,Yellow) print_info2() fin = floor(cen+p2xy(r,3600 * pifac))--=pre loop timedelta = time() radarspeed = 40 while getControlInfo(self, CONTROLINFO_closed) != 1 do doEvents(0) UpdateRadar() end while end procedure setHandler( Window1, w32HActivate,routine_id("setup")) WinMain( Window1,Normal )
-- Derek Parnell Melbourne, Australia Skype name: derek.j.parnell