How bygge en Python Bot som kan spille Web Games
86
Del
63
Share < .no> Dette Cyber mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.
I denne opplæringen vil vi utforske ins og outs av å bygge en Computer Vision-basert spill bot i Python, som vil være i stand til å spille den populære Flash spillet Sushi Go Round. Du kan bruke teknikker lært i denne opplæringen for å lage roboter for automatisk å teste dine egne web-spill.
Endelig resultat Forhåndsvisning
La oss ta en titt på det endelige resultatet vi skal jobbe mot:
Forutsetninger
Denne opplæringen, og all koden i det, krever at noen flere Python bibliotekene skal installeres. De gir en fin Python innpakning til en haug med lavt nivå C-kode som i stor grad forenkler prosessen og hastigheten på bot scripting.
Noen av koden og biblioteker er Windows-spesifikke. Det kan være Mac- eller Linux-ekvivalenter, men vi vil ikke dekke dem i denne opplæringen
Du må laste ned og installere følgende biblioteker.
Numpy
PyWin
Alle de ovennevnte har selv installatører; Kjører dem vil automatisk installere modulene i din \\ lib \\ site-pakker katalogen og i teorien justere PYTHONPATH tilsvarende. Men i praksis er dette ikke alltid skjer. Skulle du begynne å motta noen Import Feilmeldinger etter installasjon, vil du sannsynligvis trenger å justere Miljøvariabler manuelt. Mer informasjon om justering Sti Variabler kan bli funnet her.
Det siste verktøyet vi trenger er en anstendig tegneprogram. Jeg foreslår Paint.NET som et utmerket gratis alternativ, men et program med herskere som viser sine målinger i piksler kan brukes.
Vi vil bruke et par spill som eksempler underveis
Innledning
Denne veiledningen er skrevet for å ga en grunnleggende innføring i ferd med å bygge roboter som spiller nettleserbaserte spill. Tilnærmingen vi kommer til å ta er trolig litt annerledes enn hva de fleste forventer når de tenker på en bot. Snarere enn å lage et program som sitter mellom klient og server injisere kode (som en Quake eller C /S bot), vil vår bot sitte utelukkende på "utenfor". Vi skal stole på Computer Vision-esque teknikker og Windows API-kall for å samle nødvendig informasjon og generere bevegelse.
Med denne tilnærmingen mister vi litt av raffinert detalj og kontroll, men gjør opp for det i forkortet dev tid og brukervennlighet. Automatisere en bestemt spill funksjon kan gjøres i noen korte linjer med kode, og en fullverdig, start-til-avslutning bot (for et enkelt spill) kan sveives ut i et par timer.
Gleden av denne raske tilnærmingen er slik at når du blir kjent med hva maskinen kan lett "se", vil du begynne å se spill litt annerledes. Et godt eksempel er funnet i puzzle-spill. En vanlig konstruksjon innebærer å utnytte menneskelige hastighetsbegrensninger for å tvinge deg til en mindre enn optimal løsning. Det er morsomt (og ganske lett) å "pause" i disse spillene av scripting i bevegelser som aldri kunne oppnås ved et menneske
Disse botene er også svært nyttig for å teste enkle spill -. Motsetning et menneske, en bot won 't bli lei å spille samme scenario om og om igjen.
Kildekode for alle opplæringen eksempler, samt for en av de ferdige eksempel roboter, kan bli funnet her.
Ha det gøy
Trinn 1: Opprett en ny Python Prosjekt
I en ny mappe, høyreklikk og velg Ny > Tekstdokument.
Når gjort, endre navn på filen fra "New Tekstdokument" til "quickGrab.py" (uten anførselstegn) og bekrefter at du ønsker å endre filtypen.
Til slutt, høyreklikker du på vår nyopprettede filen og velg "Edit with IDLE" fra hurtigmenyen for å starte redaktør
Trinn 2: Sette opp din første Screen Grab
vil begynne arbeidet med vår bot ved å utforske grunnskjermen grab funksjon. Når oppe og går, vil vi gå gjennom det linje for linje, som denne funksjonen (og dens mange iterasjoner) vil fungere som ryggraden i vår kode
I quickgrab.py skriv inn følgende kode:.
import ImageGrabimport osimport timedef screengrab (): boks = () im = ImageGrab.grab () im.save (os.getcwd () + '\\\\ full_snap__' + str (int (time.time ())) + ". png ',' PNG ') def main (): screengrab () hvis __name__ ==' __main__ ': main ()
Kjøre dette programmet skal gi deg en full snapshot av skjermen området:
gjeldende koden griper hele bredden og høyden på skjermen området og lagrer den som en PNG i din nåværende arbeidskatalog.
La oss nå gå gjennom koden for å se nøyaktig hvordan det fungerer.
tre første linjene:
import ImageGrabimport osimport tid
... er de treffende navnet "import uttalelser". Disse forteller Python å laste i de nevnte modulene under kjøring. Dette gir oss tilgang til deres metoder via module.attribute syntaks.
Den første modulen er en del av Python Bildearkiv vi installert tidligere. Som navnet antyder, det gir oss den grunnleggende skjermen gabbing funksjonalitet vår bot vil stole på.
Den andre linjen importerer OS (Operating System) Module. Dette gir oss muligheten til enkelt å navigere rundt vår operativsystemet kataloger. Det vil komme godt med når vi begynne å organisere eiendeler i ulike mapper.
Dette siste import er den innebygde tids modulen. Godt bruke dette hovedsakelig for stempling gjeldende tid på øyeblikksbilder, men det kan være svært nyttig som en timer for roboter som trenger hendelser utløst over et gitt antall sekunder.
De neste fire linjene utgjør hjertet av vår screengrab () -funksjonen
def screengrab (). boks = () im = ImageGrab.grab () im.save (os.getcwd () + '\\\\ full_snap__' + str (int (time.time ()) ) + 'PNG', 'PNG')
Den første linjen def screengrab () definerer navnet på funksjonen. De tomme parentes betyr det forventer ingen argumenter.
Linje 2, boks = () tildeler en tom tuppel til en variabel som heter "boksen". Vi vil fylle dette med argumenter i neste trinn.
Linje 3, im = ImageGrab.grab () oppretter en full skjermbilde og returnerer et RGB-bilde til forekomsten im
Linje 4 kan være litt vanskelig hvis du ikke er kjent med hvordan Time modulen fungerer. Den første delen im.save (kaller "redde" metoden fra bilde klassen. Det forventer to Her har vi satt plasseringen ved først å ringe os.getcwd (). Dette blir den gjeldende katalogen koden blir kjørt fra og returnerer det som en streng. Vi neste legge et +. Dette vil bli brukt i mellom hver nytt argument for å sette sammen alle strengene sammen. Det neste stykket '\\\\ full_snap__ gi vår fil en enkel beskrivende navn. (Fordi skråstrek er en flukt karakter i Python, må vi legge til to av dem til unngå avbryter ut en av våre bokstaver) Neste er hårete bit:.. str (int (time.time ())) Dette tar nytte av Python innebygde type metoder Vi skal forklare dette stykket. ved å jobbe fra innsiden og ut: time.time () returnerer antall sekunder siden Epoch, som er gitt som en type Float Siden vi skaper et filnavn vi kan ikke ha desimal i. der, så vi først konvertere den til et heltall ved å pakke den i int (). Dette får oss nær, men Python kan ikke sette sammen typen Int med type String, så det siste trinnet er å pakke alt i str () -funksjonen til å gi oss en fin brukbare tidsstempel for filnavnet. Herfra er alt som gjenstår å legge utvidelsen som en del av strengen: + '.png' og passerer det andre argumentet som er igjen forlengelsen type. "PNG" Den siste delen av vår kode definerer funksjonen main (), og forteller det til å ringe screengrab () -funksjonen når det kjøres. Og her, på slutten, er en Python konvensjon som sjekker om manuset er øverste nivå, og i så fall kan det å kjøre. Oversatt, betyr det bare at at det bare utfører main () hvis det er drevet av seg selv. Ellers - hvis, for eksempel, er det lastet som en modul av en annen Python-skript - den bare leverer sine metoder i stedet for å gjennomføre sin kode ImageGrab.grab () -funksjonen godtar ett argument som definerer en markeringsrammen. Dette er et tuppel av koordinater etter mønster av (x, y, x, y) der, etter Ved å kombinere disse tillater oss å bare kopiere den delen av skjermen vi trenger. La oss sette dette ut i praksis. I dette eksemplet skal vi bruke et spill som heter Sushi Go Round. (.. Ganske Et øyeblikksbilde av hele skjermområdet. Nå er det på tide å begynne gruvedrift noen koordinater for vår markeringsrammen Åpne opp din siste bilde i et bilderedigeringsprogram.. (0,0) posisjon er alltid plassert øverst i venstre hjørne av bildet. Vi ønsker å pad x- og y-koordinater slik at våre nye snapshot funksjonssett (0,0) til den nest siste hjørnet av spillets lekeområde. Årsakene til dette er todelt. Først, det gjør funn i spillet koordinerer mye lettere når vi trenger bare å justere verdier i forhold til lekeområde versus hele området av skjermoppløsningen. Sekund, flytte en mindre del av skjermen reduserer behandlings overhead kreves. Full skjermen griper produsere ganske mye data, noe som kan gjøre det vanskelig å krysse det flere ganger per sekund. Hvis ikke gjort allerede, aktivere linjal skjerm i editor og zoome inn på den øverste hjørne av lekeområde til du kan se pikslene i detalj: Hold markøren over den første piksel av lekeområdet og kontrollere koordinatene som vises på linjalen. Disse vil være de to første verdiene av vår Box tuppel. På min bestemt maskin disse verdiene er 157, 162. Naviger til underkant av lekeområdet for å få bunnen par koordinater. Dette viser koordinatene til 796 og 641. Ved å kombinere disse . med vår forrige paret gir en boks med koordinatene (157162796641) La oss legge denne til vår kode I linje 6 har vi oppdatert tuppel å holde koordinatene til lekeområdet Lagre og kjøre koden.. Åpne opp den nylig lagrede bildet og du skal se: Suksess! En perfekt grip av lekeområdet. Vi vil ikke alltid trenger å gjøre denne typen intensiv jakt på koordinater. Når vi kommer inn i Win32API vi vil gå over noen raskere metoder for å sette koordinatene når vi ikke trenger pixel perfekt nøyaktighet Som det står nå, vi har hardkodet koordinatene i forhold til vår nåværende oppsett, forutsatt at vår Så vi kommer til å opprette to nye variabler: x_pad og y_pad. Disse vil bli brukt til å lagre forholdet mellom spillområdet og resten av skjermen. Dette vil gjøre det svært enkelt å port koden fra sted til sted siden hver ny koordinat vil være i forhold til de to globale variabler vi skal skape, og å justere for endringer i skjermområdet, er alt som kreves for å tilbakestille disse to variabler. Siden vi allerede har gjort målingene, sette putene for vårt nåværende system er veldig grei. Vi kommer til å sette pads å lagre plasseringen av den første piksel utsiden av lekeområdet. Fra første par x, koordinerer y i vår boks tuppel, trekke en en fra hver verdi. Så 157 blir 156, og 346 blir 345. La oss legge denne til vår kode. Nå som disse er satt, vil vi begynne å justere boksen tuppel å være i forhold til disse verdiene For andre paret, skal vi først trekke verdiene av pads (156 og 345) fra koordinatene (796, 825), og deretter bruke disse verdiene i samme Pad + Verdi format Her x koordinat blir 640 (769-156), og y blir 480 (825-345) Det kan virke litt overflødig i starten, men å gjøre dette ekstra trinnet sikrer enkelt vedlikehold i fremtiden Før vi går videre, vi kommer til å lage en docstring på toppen av vårt prosjekt. Siden de fleste av våre kode vil være basert rundt spesifikke skjermkoordinater og relasjoner til En siste ting å være klar over er den stadig skiftende annonseplass på populære spillsider . Hvis alle dine grab samtaler plutselig slutte å oppføre seg som forventet, en ny legge litt skiftende ting på skjermen er en god innsats Som et eksempel, jeg har som regel følgende kommentarer på toppen av min Python-kode:. Slippe all denne informasjonen i begynnelsen av Python-filen gjør det raskt og enkelt å dobbeltsjekke alle dine innstillinger og skjermen justering uten å måtte pore over koden din prøver å huske hvor du lagres som én bestemt x-koordinat Vi kommer til å punge vårt prosjekt på dette punktet, og skaper to filer: en til å holde alle våre bot kode, og den andre til å fungere som en generell skjermbilde verktøyet. Vi kommer til å ta mye av skjermbilder som vi jakte på koordinatene, så har en egen modul klar til å gå vil gjøre ting mye Raskere. Lagre og lukk vårt nåværende prosjekt. Nå høyreklikk og velg "lime" fra menyen Velg den kopierte filen og endre navnet til "code.py ' Fra nå av skal alle nye kode tilføyelser og endringer vil bli gjort i code.py. quickGrab.py vil nå fungere som en ren snapshot verktøy. Vi trenger bare å gjøre en siste modifikasjon. Endre filtypen fra .py, til .pyw og bekrefte endringene Denne utvidelsen forteller Python å kjøre skriptet uten å lansere konsollen. Så nå lever quickGrab.pyw opp til navnet sitt. Dobbeltklikk på filen og det vil stille utføre sin kode i bakgrunnen og lagre et øyeblikksbilde til din arbeidsmappen. Hold spillet åpent i bakgrunnen (husk å dempe den før loopet musikk driver deg til galskap); vi vil komme tilbake til det om kort tid. Vi har noen flere konsepter /verktøy for å innføre før vi kommer inn i styre ting på skjermen Arbeide med Win32API kan være en litt skremmende i starten. Det brytes lavnivå Windows C-kode - som er heldigvis veldig Før vi starter. skripting noen nyttige handlinger, skal vi ta en nærmere titt på noen av API-funksjoner hvorpå vi skal stole. Når vi har en klar forståelse av hver parameter vil det være lett å justere dem for å tjene det formål vi trenger i spillet win32api.mouse_event (). Den første parameteren dwFlags definerer "action" på musen. Den styrer ting som bevegelse, klikke, rulle, etc .. Følgende liste viser de vanligste parametrene brukes mens scripting movement. dwFlags: Each Navnet er selvforklarende. Hvis du ønsket å sende en virtuell høyreklikk, du ville passere win32con.MOUSEEVENTF_RIGHTDOWN til dwFlags parameter. Den neste to parametre, dx og dy, beskrive musens absolutte posisjon langs x og y-aksen. Mens vi kunne bruke disse parametrene for skripting musen bevegelse, de bruker et koordinatsystem annerledes enn den vi har brukt. Så vil vi la dem satt til null og stole på en annen del av API for vår musen beveger behov. Den fjerde parameter er dwData. Denne funksjonen brukes hvis (og bare hvis) dwFlags inneholder MOUSEEVENTF_WHEEL. Ellers er kan utelates eller satt til null. dwData angir hvor mye bevegelse på musens rullehjul Et raskt eksempel å stivne disse teknikkene:. Hvis vi tenker oss et spill med et utvalg våpen system som ligner på Half-Life 2 - hvor våpen kan velges ved å rotere musehjulet - vi ville komme opp med følgende funksjon å sile gjennom listen med våpen: Her er vi ønsker å simulere rulle musehjulet til å navigere vår teoretiske våpen notering, så vi passerte ... MOUSEEVENTF_WHEEL handlingen 'til den dwFlag. Vi trenger ikke dx eller dy, posisjonsdata, slik at vi igjen de som er satt til null, og vi ønsket å bla ett klikk i retning fremover for hver "våpen" i listen, så vi passerte heltallet 120 til dwData (hver hjulet klikk lik 120). Som du kan se, som arbeider med mouse_event er bare et spørsmål om å koble de riktige argumentene til rett sted. La oss nå flytte inn på noen mer brukbare funksjoner Vi kommer til å lage tre nye funksjoner. En generell venstreklikk funksjon, og to som håndterer den spesifikke ned og opp statene Åpne code.py med IDLE og legge til følgende til vår liste over import uttalelser. Som før, dette gir oss tilgang til modulens innhold via module.attribute syntaks Neste vi vil gjøre vårt første museklikk funksjon Husk at alt vi gjør her er å tildele en "handling" til det første argumentet mouse_event. Vi trenger ikke å passere noen posisjonsinformasjon, så vi drar koordinatsystemet parametre (0,0), og vi trenger ikke å sende noen ekstra info, så dwData blir utelatt. Den time.sleep (0,1) -funksjonen forteller Python å stanse henrettelsen for tiden angitt i parentes. Vi vil legge til disse gjennom vår kode, vanligvis for svært kort tid. Uten disse, kan den "klikke" komme i forkant av seg selv og brann før menyer har en sjanse til å oppdatere. Så det vi har gjort her er en generell venstreklikk. Ett trykk, en utgivelse. Vi vil tilbringe mesteparten av vår tid med dette, men vi kommer til å gjøre to flere varianter. Den neste to er akkurat det samme, men nå hvert trinn er delt inn i sin egen funksjon. Disse vil bli brukt når vi trenger å holde nede muse for en lang tid (for å dra, skyting, etc ..) Med klikke ut av veien alt som er igjen er å bevege musen rundt på skjermen Legg følgende funksjoner til code.py: Disse to funksjoner tjene distinkt forskjellige formål. Den første vil bli brukt for skripting bevegelse i programmet. Takket være gode navnekonvensjoner, gjør kroppen av funksjon akkurat som SetCursorPos () tilsier. Calling denne funksjonen setter musen til koordinatene sendes til den som . en x, y tuppel Legg merke til at vi har lagt til i vår x og y pads; det er viktig å gjøre dette hvor som helst et koordinatsystem kalles. Den andre er et enkelt verktøy som vi bruker når du kjører Python interaktivt. Den skriver til konsollen den aktuelle posisjonen til musen som en x, y tuppel. Dette gjør sterkt opp prosessen med å navigere gjennom menyene uten å måtte ta et øyeblikksbilde og bryte ut en linjal. Vi vil ikke alltid være i stand til å bruke den, som noen mus aktiviteter må være pixel-spesifikke, men når vi kan, det er en fantastisk tid saver. I neste trinn vil vi sette noen av disse nye teknikker for å bruke og begynne å navigere i spillet menyer. Men før vi gjør det, slette det gjeldende innholdet i main () i code.py og erstatte den med pass. Vi kommer til å jobbe med interaktiv teksten for neste steg, så vi vil ikke være behov screengrab () -funksjonen I denne og de neste trinnene, skal vi forsøke å samle så mange arrangement koordinater som vi kan bruke våre get_cords () metoden. Ved hjelp av det vil vi være i stand til å raskt bygge opp koden for ting som du navigerer menyer, rydde bord, og lager mat. Når vi har disse sett, vil det bare være et spørsmål om å hekte dem i bot logikk. La oss komme i gang. Lagre og kjøre koden din for å få opp Python skallet. Siden vi erstattet kroppen av main () med pass i det siste trinnet, bør du se en tom skall på løping. Nå, før vi selv komme til spillbare delen av spillet er det fire innledende menyer vi trenger for å komme gjennom. De er som følger: Vi må få koordinatene for hver av disse og legge dem til en ny funksjon kalt startGame (). Plasser IDLE skallet slik at du kan se både den og lekeområde. Skriv inn get_cords () funksjon, men ikke trykk retur ennå; bevege musen over knappen som du trenger koordinater. Pass på å ikke klikke ennå, så vi vil fokusere å forbli i skallet. Hold musen over menyvalget og nå La skallet åpen og ordne det slik at du kan se det i tillegg til IDLE redaktør. Vi nå kommer til å nå legge vår startGame () funksjon og fylle den med våre nyervervede koordinater Vi har nå en fin kompakt funksjon for å ringe ved starten av hvert spill. Det setter markøren til hver av meny steder vi tidligere definerte, og så forteller musen til å klikke. time.sleep (0,1) forteller Python å stanse henrettelsen for 1/10 av et sekund mellom hvert klikk, noe som gir menyene nok tid til å oppdatere i mellom. Lagre og kjøre koden din, og du skal se en resultere ligner på dette: Som en svak menneske det tar meg litt lengre enn et sekund å navigere alle menyene for hånd, men vår bot kan nå gjøre det i ca 0,4 sekunder. Ikke verst i det hele tatt Nå er vi kommer til å gjenta den samme prosessen for hver av disse knappene: Nok en gang i Python skallet, skriv i get_cords (), holder du musepekeren over maten boksen du trenger, og trykk på Enter-tasten for å utføre kommandoen. Som et alternativ til ytterligere fart på sakene sammen, hvis du har en ekstra skjerm, eller er i stand til å arrangere den python shell på en måte som du kan se det, så vel som spillområdet, i stedet for å skrive inn og kjører get_cords () hver gang vi trenger det, kan vi sette opp en enkel for loop . Bruk en time.sleep () metoden for å stanse henrettelsen akkurat lenge nok for deg å flytte musen til neste lokasjon trenger koordinater Her er det for loop i aksjon. Vi kommer å opprette en ny klasse kalt Cord og bruke den til å lagre alle koordinatverdiene vi samles. Å kunne kalle Cord.f_rice tilbyr et stort lesbarhet fordel over passerer koordinatene direkte til mousePos (). Som et alternativ, kan du også lagre alt i en ordbok, men jeg synes den klassen syntaks morsommere Vi kommer til å lagre mye av våre koordinater i denne klassen, og det vil være noe overlapping, så legger den "F_ 'prefiks forteller oss at vi henvise til maten steder, heller enn, si, en plassering i telefonmenyen. Vi kommer tilbake til disse i en bit. Det er litt mer koordinere jakt å gjøre Hver gang en kunde er ferdig å spise, etterlater de seg en plate som må klikket på som skal fjernes. Så vi trenger å få plasseringen av tomme plater også. Jeg har lagt merke til deres posisjon med en gigantisk rød "X". Gjenta samme mønster som i de to siste trinnene for å få sine koordinater. . Lagre dem i kommentarfeltet streng for nå Vi får tett. Bare et par skritt av foreløpige oppsettet før vi kommer inn i virkelig morsomme ting Ok, dette blir det siste settet med koordinater vi har til meg i denne bestemt måte. Denne har mye mer å holde styr på, så det kan være lurt å gjøre det manuelt ved å ringe get_cords () -funksjonen i stedet for den tidligere brukte for loop-metoden. Uansett, vi kommer til å gå gjennom alle telefonmenyene for å få koordinatene for hvert element. Dette er litt mer involvert som å nå en av de innkjøps skjermene vi trenger, må du har nok penger til å faktisk kjøpe noe. Så du trenger å gjøre et par stykker av sushi før du går om virksomheten Koordinasjon jakt. På det meste, må du gjøre to sushi ruller, tror jeg. Som vil få deg nok til å kjøpe litt ris, som vil få oss til skjermen vi trenger Det er seks menyer vi har å komme gjennom. Vi trenger å få koordinatene for alt, men Sake (selv om du kan hvis du . ønsker jeg fant bot fungerte fint uten det jeg var villig til å ofre en og annen dårlig i spillet anmeldelse for ikke å måtte kode i logikken) Å få koordinatene:.. 're kommer til å legge alle disse til vår Cord klasse. Vi vil bruke prefikset 'T_ "for å betegne at typer mat er telefon > elementer fyllinger eller meny Alright! Vi har endelig minelagt alle koordinatverdiene vi trenger. Så la oss begynne å gjøre noe nyttig Vi kommer til å ta våre tidligere innspilte koordinater og bruke dem til å fylle en funksjon som heter clear_tables () Som du kan se, dette ser mer eller mindre akkurat som vår tidligere startGame () -funksjonen . Noen små forskjeller: Vi har ingen time.sleep () funksjoner mellom de forskjellige klikk hendelser. Vi trenger ikke å vente på noen menyer for å oppdatere, så vi trenger ikke å strupe våre klikk hastigheter. Vi gjør imidlertid ha en lang time.sleep () helt på slutten. Selv om ikke strengt nødvendig, er det fint å legge til disse sporadiske pauser i kjøringen til vår kode, noe akkurat lenge nok gi oss tid til å manuelt bryte ut av bot hoved sløyfe om nødvendig (som vi vil komme til). Ellers vil ting fortsette å stjele musen posisjon igjen og igjen, og du vil ikke være i stand til å skifte fokus til skallet lenge nok til å stoppe skriptet - som kan morsomt de første to eller tre ganger så du kjempe mot en mus , men den mister fort sin sjarm Så sørg for å legge inn noen pålitelige pauser i dine egne roboter Den første ting vi trenger å gjøre er å lære å lage sushi. Klikk på oppskriftsbok for å åpne bruksanvisningen. Alle sushi typer oppstått gjennom hele spillet vil bli funnet innenfor sine sider. Jeg vil merke de første tre under, men jeg la det til deg å katalog resten Nå skal vi sette opp en funksjon som vil akseptere et argument for "sushi type" og deretter sette sammen de riktige ingredienser basert på passert verdien. Providing
argumenter. Den første er stedet der du vil lagre filen, og den andre er filformatet.
def main (): screengrab () hvis __name__ == '__main__': main. ()
Trinn 3: The markeringsramme
Det første paret med verdier (x, y .. definerer øvre venstre hjørne av boksen
Det andre paret ..x, y) definerer nederst til høyre.
addicting Du har blitt advart) Åpne spillet i en ny fane, og ta et stillbilde med vår eksisterende screengrab () kode:
Trinn 4: Få Koordinater
import ImageGrabimport osimport timedef screengrab (). boks = (157346796825) im = ImageGrab.grab ( boks) im.save (os.getcwd () + '\\\\ full_snap__' + str (int (time.time ())) + 'PNG', 'PNG') def main (): screengrab () hvis __name__ = = '__main__': main ()
Trinn 5:. Planlegging fremover for Fleksibilitet
nettleser, og vår
oppløsning. Det er generelt en dårlig idé å hard-kode koordinater på denne måten. Hvis, for eksempel, vi ønsker å kjøre kode på en annen datamaskin - eller si, en ny annonse på nettstedet skifter posisjon av lekeområdet litt - vi måtte manuelt og møysommelig fikse alle våre koordinere samtaler
# Globals # ------------------ x_pad = 156y_pad = 345
def screengrab (). boks = (x_pad + 1, y_pad + 1, 796, 825 ) im = ImageGrab.grab () im.save (os.getcwd () + '\\\\ full_snap__' + str (int (time.time ())) + 'PNG', 'PNG')
def screengrab ().: box = (x_pad + 1, y_pad + 1, x_pad + 640, y_pad + 479) im = ImageGrab.grab () im.save (os.getcwd () + '\\\\ full_snap__' + str (int (time.time ( ))) + 'PNG', 'PNG')
Trinn 6:. Opprette en Docstring
koordinater, er det viktig å vite under hvilke omstendigheter alt blir riktig. For eksempel ting som gjeldende oppløsning, nettleser, verktøylinjer aktivert (siden de endrer nettleser området), og eventuelle justeringer som trengs for å sentrere lekeområdet på skjermen, alle påvirke den relative plasseringen av koordinatene. Å ha alt dette dokumentert sterkt
hjelper feilsøkingsprosessen når du kjører koden din på tvers av flere nettlesere og datamaskiner.
"" "Alle koordinatene anta en skjermoppløsning på 1280x1024, og Chrome maksimert med bokmerker enabled.Down nøkkelen har blitt truffet 4 ganger for å sentrere lekepark i browser.x_pad = 156y_pad = 345Play areal = x_pad + 1, y_pad + 1, 796, 825 "" "
Trinn 7:. Slå quickGrab.py Into et nyttig verktøy
< p> I mappen, høyreklikker du på quickGrab.py og velg "kopier" fra menyen.
Trinn 8:. Win32API - En kort oversikt
godt dokumentert her, men litt som en labyrint å navigere gjennom første par go-arounds
Win32api.mouse_event (dwFlags, dx, dy, dwData)
win32con.MOUSEEVENTF_LEFTDOWN
win32con.MOUSEEVENTF_LEFTUP
win32con.MOUSEEVENTF_MIDDLEDOWN
win32con.MOUSEEVENTF_MIDDLEUP
win32con.MOUSEEVENTF_RIGHTDOWN
win32con.MOUSEEVENTF_RIGHTUP
win32con.MOUSEEVENTF_WHEEL
def browseWeapons (): weaponList = ['brekkjern', 'gravitasjon pistol', 'pistol' .. .] for jeg i weaponList: win32api.mouse_event (win32con.MOUSEEVENTF_MOUSEEVENTF_WHEEL, 0,0,120)
Trinn 5: Basic Mouse Klikker
Import Win32API, win32con
def leftClick ():.. win32api.mouse_event (win32con.MOUSEEVENTF_LEFTDOWN , 0,0) time.sleep (0,1) win32api.mouse_event (win32con.MOUSEEVENTF_LEFTUP, 0,0) print "Klikk". #completely valgfritt. Men hyggelig for debugging formål.
def leftDown (). Win32api.mouse_event (win32con.MOUSEEVENTF_LEFTDOWN, 0,0) tid. søvn (0,1) print "venstre Down 'def leftUp (): win32api.mouse_event (win32con.MOUSEEVENTF_LEFTUP, 0,0) time.sleep (0,1) print" venstre release "
Trinn 9: Basic Mouse . bevegelse
def mousePos (cord): Win32API. SetCursorPos ((x_pad + ledningen [0], y_pad + ledningen [1]) def get_cords (): x, y = win32api.GetCursorPos () x = x - x_pad y = y - y_pad print x, y
Trinn 10:. Navigere Spill Menyer
Første "play" -knappen
iPhone "fortsette" -knappen
Tutorial "Skip" -knappen
Dagens mål " Fortsett "knappen
trykk på returtasten. Dette vil ta tak i nåværende plassering av musen og skrive til konsollen et tuppel som inneholder x, y-verdiene. Gjenta dette for de resterende tre menyer.
def startGame (). #location Av første meny mousePos ((182, 225)) leftClick () time.sleep ( 0,1) #location av andre meny mousePos ((193, 410)) leftClick () time.sleep (0,1) #location av tredje meny mousePos ((435, 470)) leftClick () time.sleep (0,1) # Plasseringen av fjerde meny mousePos ((167, 403)) leftClick () time.sleep (0,1)
Trinn 11: Får Mat Koordinater
klasse Cord. F_shrimp = (54700) f_rice = (119 701) f_nori = (63 745) f_roe = (111 749 ) f_salmon = (54 815) f_unagi = (111 812)
Trinn 12: Får Empty Plate Koordinater
"" "plate snorer: 108, 573 212, 574 311, 573 412, 574 516, 575 618, 573" ""
Trinn 13:. Får Phone Koordinater
The Phone Anmeldelser
Første Meny
Topping
Rice
Shipping
klasse Cord. F_shrimp = (54700) f_rice = (119 701) f_nori = (63 745) f_roe = (111 749) f_salmon = (54 815) f_unagi = (111 812) # ----------------------------------- telefonen = (601, 730) menu_toppings = (567, 638) t_shrimp = (509, 581) t_nori = (507, 645) t_roe = (592, 644) t_salmon = (510, 699) t_unagi = (597, 585) t_exit = ( 614, 702) menu_rice = (551, 662) buy_rice = 564, 647 delivery_norm = (510, 664)
Trinn 14:!. Rydde bord
def clear_tables (): mousePos ((108, 573)) leftClick () mousePos ((212, 574)) leftClick () mousePos ((311, 573)) leftClick () mousePos ((412, 574)) leftClick ( ) mousePos ((516, 575)) leftClick () mousePos ((618, 573)) leftClick () time.sleep (1)
Trinn 15:.! Making Sushi
'' 'oppskrifter. Onigiri to ris, en nori caliroll: 1 ris, en nori, en rogn gunkan: 1 ris, en nori, 2 rogn '' '
def makeFood (mat) : Hvis mat == 'caliroll': print 'Making en caliroll' mousePos (Cord.f_rice) leftClick () time.sleep (.05) mousePos (Cord.f_nori) leftClick () time.sleep (.05) mousePos (Cord available'mousePos(Cord.buy_rice)time.sleep(.1)leftClick()mousePos(Cord.delivery_norm)time.sleep(.1)leftClick()time.sleep(2.5)